1、API升级

Former-commit-id: 204edfa284643d8e0b366ef5db42e4217e0230e4
master
wangbing 5 years ago
parent 275599c5fb
commit cf42b08ad0

@ -20,7 +20,6 @@ public class ApiCallable implements Callable {
private File req; private File req;
private File rsp; private File rsp;
private File ent; private File ent;
private File enums;
private List<Api> apiList; private List<Api> apiList;
private Tool tool = new Tool(); private Tool tool = new Tool();
@ -31,7 +30,6 @@ public class ApiCallable implements Callable {
this.req = req; this.req = req;
this.rsp = rsp; this.rsp = rsp;
this.ent = ent; this.ent = ent;
this.enums = enums;
this.apiList = apiList; this.apiList = apiList;
this.freeMarkerManager = ManagerFactory.getFreeMarkerManager(); this.freeMarkerManager = ManagerFactory.getFreeMarkerManager();
} }
@ -136,7 +134,7 @@ public class ApiCallable implements Callable {
ctx.put("findOrSearchflag", javaClassReader.getFindOrSearchflag()); ctx.put("findOrSearchflag", javaClassReader.getFindOrSearchflag());
File file = new File(request.getAbsolutePath(), api.getReq().getName()); File file = new File(request.getAbsolutePath(), api.getReq().getName());
freeMarkerManager.outputTemp(file, "Java_api/module/request/request.ftl", ctx); freeMarkerManager.outputTemp(file, "Java_api/module/request/request.java", ctx);
System.out.println("生成文件" + file.getName() + "成功"); System.out.println("生成文件" + file.getName() + "成功");
} }
//endregion //endregion
@ -169,7 +167,7 @@ public class ApiCallable implements Callable {
ctx.put("Tclass", javaClassReader.getTclass()); ctx.put("Tclass", javaClassReader.getTclass());
File file = new File(response.getAbsolutePath(), api.getRsp().getName().replaceAll("Request", "Response")); File file = new File(response.getAbsolutePath(), api.getRsp().getName().replaceAll("Request", "Response"));
freeMarkerManager.outputTemp(file, "Java_api/module/response/response.ftl", ctx); freeMarkerManager.outputTemp(file, "Java_api/module/response/response.java", ctx);
System.out.println("生成文件" + api.getRsp().getName() + "成功"); System.out.println("生成文件" + api.getRsp().getName() + "成功");
} }
//endregion //endregion
@ -213,7 +211,7 @@ public class ApiCallable implements Callable {
ctx.put("findOrSearchflag", javaClassReader.getFindOrSearchflag()); ctx.put("findOrSearchflag", javaClassReader.getFindOrSearchflag());
File file = new File(request.getAbsolutePath(), f.getName()); File file = new File(request.getAbsolutePath(), f.getName());
freeMarkerManager.outputTemp(file, "Java_api/module/request/request.ftl", ctx); freeMarkerManager.outputTemp(file, "Java_api/module/request/request.java", ctx);
System.out.println("生成文件" + file.getName() + "成功"); System.out.println("生成文件" + file.getName() + "成功");
} }
//endregion //endregion
@ -248,7 +246,7 @@ public class ApiCallable implements Callable {
ctx.put("Tclass", javaClassReader.getTclass()); ctx.put("Tclass", javaClassReader.getTclass());
File file = new File(response.getAbsolutePath(), f.getName()); File file = new File(response.getAbsolutePath(), f.getName());
freeMarkerManager.outputTemp(file, "Java_api/module/response/response.ftl", ctx); freeMarkerManager.outputTemp(file, "Java_api/module/response/response.java", ctx);
System.out.println("生成文件" + api.getRsp().getName() + "成功"); System.out.println("生成文件" + api.getRsp().getName() + "成功");
} }
//endregion //endregion
@ -284,7 +282,7 @@ public class ApiCallable implements Callable {
ctx.put("body", javaClassReader.getBody()); ctx.put("body", javaClassReader.getBody());
ctx.put("tool", tool); ctx.put("tool", tool);
File file = new File(entity.getAbsolutePath(), f.getName()); File file = new File(entity.getAbsolutePath(), f.getName());
freeMarkerManager.outputTemp(file, "Java_api/module/entity/entity.ftl", ctx); freeMarkerManager.outputTemp(file, "Java_api/module/entity/entity.java", ctx);
System.out.println("生成文件" + file.getName() + "成功"); System.out.println("生成文件" + file.getName() + "成功");
} }
//endregion //endregion
@ -292,49 +290,7 @@ public class ApiCallable implements Callable {
e.printStackTrace(); e.printStackTrace();
} }
} }
for (String s : api.getDepEnum()) {
try {
File f = new File(enums, s + ".java");
if (!f.exists()) {
System.err.println("文件" + f.getAbsolutePath() + "不存在");
continue;
}
JavaEnumReader javaEnumReader = new JavaEnumReader(f);
{
HashMap<String, Object> ctx = new HashMap<String, Object>();
ctx.put("package", "package " + javaEnumReader.getDomainName() + "." + javaEnumReader.getModuleName() + "." + "enums;");
ctx.put("domain", javaEnumReader.getDomainName());
ctx.put("module", javaEnumReader.getModuleName());
ctx.put("annotation", javaEnumReader.getAnnotationList());
ctx.put("className", javaEnumReader.getClassName());
ctx.put("body", javaEnumReader.getBody());
ctx.put("tool", tool);
File file = new File(enumeration, f.getName());
freeMarkerManager.outputTemp(file, "Java_api/module/enums/type.ftl", ctx);
System.out.println("生成文件" + file.getName() + "成功");
}
//endregion
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }
{
System.out.println("生成模块:ApiController");
HashMap<String, Object> ctx = new HashMap<String, Object>();
ctx.put("tool", tool);
ctx.put("domain", javaClass.getDomainName());
ctx.put("module", javaClass.getModuleName());
ctx.put("managerList", managerList);
ctx.put("methodList", methodList);
File file = new File(domain.getAbsolutePath() + File.separator + "ApiController.java");
freeMarkerManager.outputTemp(file, "Java_api/module/controller/ApiController.ftl", ctx);
} }
{ {
@ -344,11 +300,11 @@ public class ApiCallable implements Callable {
ctx.put("module", javaClass.getModuleName()); ctx.put("module", javaClass.getModuleName());
{ {
File file = new File(domain, "ApiEntity.java"); File file = new File(domain, "ApiEntity.java");
freeMarkerManager.outputTemp(file, "/Java_api/ApiEntity.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ApiEntity.java", ctx);
} }
{ {
File file = new File(domain, "AESUtil.java"); File file = new File(domain, "AESUtil.java");
freeMarkerManager.outputTemp(file, "/Java_api/AESUtil.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/AESUtil.java", ctx);
} }
{ {
File file = new File(domain, "ApiClient.java"); File file = new File(domain, "ApiClient.java");
@ -356,79 +312,71 @@ public class ApiCallable implements Callable {
} }
{ {
File file = new File(domain, "ApiRequest.java"); File file = new File(domain, "ApiRequest.java");
freeMarkerManager.outputTemp(file, "/Java_api/ApiRequest.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ApiRequest.java", ctx);
} }
{ {
File file = new File(domain, "ApiFindRequest.java"); File file = new File(domain, "ApiFindRequest.java");
freeMarkerManager.outputTemp(file, "/Java_api/ApiFindRequest.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ApiFindRequest.java", ctx);
} }
{ {
File file = new File(domain, "ApiSearchRequest.java"); File file = new File(domain, "ApiSearchRequest.java");
freeMarkerManager.outputTemp(file, "/Java_api/ApiSearchRequest.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ApiSearchRequest.java", ctx);
} }
{ {
File file = new File(domain, "ApiResponse.java"); File file = new File(domain, "ApiResponse.java");
freeMarkerManager.outputTemp(file, "/Java_api/ApiResponse.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ApiResponse.java", ctx);
} }
{ {
File file = new File(domain, "ApiFindResponse.java"); File file = new File(domain, "ApiFindResponse.java");
freeMarkerManager.outputTemp(file, "/Java_api/ApiFindResponse.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ApiFindResponse.java", ctx);
} }
{ {
File file = new File(domain, "Base64Util.java"); File file = new File(domain, "Base64Util.java");
freeMarkerManager.outputTemp(file, "/Java_api/Base64Util.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/Base64Util.java", ctx);
} }
{ {
File file = new File(domain, "DownloadUtil.java"); File file = new File(domain, "DownloadUtil.java");
freeMarkerManager.outputTemp(file, "/Java_api/DownloadUtil.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/DownloadUtil.java", ctx);
} }
{ {
File file = new File(domain, "Error.java"); File file = new File(domain, "Error.java");
freeMarkerManager.outputTemp(file, "/Java_api/Error.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/Error.java", ctx);
} }
{ {
File file = new File(domain, "ErrorType.java"); File file = new File(domain, "ErrorType.java");
freeMarkerManager.outputTemp(file, "/Java_api/ErrorType.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ErrorType.java", ctx);
}
{
File file = new File(domain, "FileUploadRequest.java");
freeMarkerManager.outputTemp(file, "/Java_api/FileUploadRequest.ftl", ctx);
}
{
File file = new File(domain, "FileUploadResponse.java");
freeMarkerManager.outputTemp(file, "/Java_api/FileUploadResponse.ftl", ctx);
} }
{ {
File file = new File(domain, "MapperUtil.java"); File file = new File(domain, "MapperUtil.java");
freeMarkerManager.outputTemp(file, "/Java_api/MapperUtil.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/MapperUtil.java", ctx);
} }
{ {
File file = new File(domain, "MD5Util.java"); File file = new File(domain, "MD5Util.java");
freeMarkerManager.outputTemp(file, "/Java_api/MD5Util.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/MD5Util.java", ctx);
} }
{ {
File file = new File(domain, "RSAUtil.java"); File file = new File(domain, "RSAUtil.java");
freeMarkerManager.outputTemp(file, "/Java_api/RSAUtil.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/RSAUtil.java", ctx);
} }
{ {
File file = new File(domain, "ProgressRequestBody.java"); File file = new File(domain, "ProgressRequestBody.java");
freeMarkerManager.outputTemp(file, "/Java_api/ProgressRequestBody.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/ProgressRequestBody.java", ctx);
} }
{ {
File file = new File(domain, "SortType.java"); File file = new File(domain, "SortType.java");
freeMarkerManager.outputTemp(file, "/Java_api/SortType.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/SortType.java", ctx);
} }
{ {
File file = new File(domain, "StringUtils.java"); File file = new File(domain, "StringUtils.java");
freeMarkerManager.outputTemp(file, "/Java_api/StringUtils.ftl", ctx); freeMarkerManager.outputTemp(file, "/Java_api/StringUtils.java", ctx);
} }
//4.0.1 去掉验证 减少体积 //4.0.1 去掉验证 减少体积
// { // {
// File file = new File(frameWork , "ValidationUtil.java"); // File file = new File(frameWork , "ValidationUtil.java");
// freeMarkerManager.outputTemp(file, "/Java_api/ValidationUtil.ftl", ctx); // freeMarkerManager.outputTemp(file, "/Java_api/ValidationUtil.java", ctx);
// } // }
} }
@ -442,7 +390,7 @@ public class ApiCallable implements Callable {
ctx.put("managerList", managerList); ctx.put("managerList", managerList);
ctx.put("methodList", methodList); ctx.put("methodList", methodList);
ctx.put("apiList", apiList); ctx.put("apiList", apiList);
freeMarkerManager.outputTemp(new File(testdomain.getAbsolutePath(), "ApiTest.java"), "Java_api/ApiTest.ftl", ctx); freeMarkerManager.outputTemp(new File(testdomain.getAbsolutePath(), "ApiTest.java"), "Java_api/ApiTest.java", ctx);
} }
System.out.println("finish"); System.out.println("finish");

@ -1,432 +0,0 @@
package ${domain};
package com.example.module;
import okhttp3.*;
import java.io.*;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.concurrent.TimeUnit;
import java.security.PublicKey;
public class ApiClient {
private static ApiClient ourInstance = null;
public static void init(String serverUrl, String appKey, String appSecret) {
init(serverUrl, appKey, appSecret, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT);
}
public static void init(String serverUrl, String appKey, String appSecret, int connectTimeout, int readTimeout) {
ourInstance = new ApiClient(serverUrl, appKey, appSecret, connectTimeout, readTimeout);
}
public static ApiClient getInstance() {
if (ourInstance == null) {
System.err.print("ApiClient need init");
}
return ourInstance;
}
//基本请求参数KEY
private static final String P_APP_KEY = "app_key";
private static final String P_TYPE = "type";
private static final String P_TARGET = "target";
private static final String P_FILE_NAME = "file_name";
private static final String P_TIMESTAMP = "timestamp";
private static final String P_METHOD = "method";
private static final String P_SIGN = "sign";
private static final String P_TOKEN = "token_id";
private static final String P_ENHANCED = "enhanced";
//参数类型
private static final String TYPE_JSON = "json";
private static final String TYPE_FILE = "file";
//应用码
private String appKey;
//应用安全码
private String appSecret;
//服务器地址
private String serverUrl;
//公钥
private PublicKey publicKey = null;
private OkHttpClient httpClient = null;
//默认参数
private static final int DEFAULT_CONNECT_TIMEOUT = 3;//秒
private static final int DEFAULT_READ_TIMEOUT = 30;//秒
//请求配置
private int connectTimeout;//3秒
private int readTimeout;//30秒
private boolean needCheckRequest = true; // 是否在客户端校验请求
private boolean needEnableParser = true; // 是否对响应结果进行解释
private Before before = null;
private After after = null;
private String token = "";
private boolean debug = false;
private ApiClient(String serverUrl, String appKey, String appSecret, int connectTimeout, int readTimeout) {
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
this.appKey = appKey;
this.appSecret = appSecret;
this.serverUrl = serverUrl;
this.httpClient = new OkHttpClient.Builder()
.readTimeout(readTimeout, TimeUnit.SECONDS)
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.build();
}
public void setPublicKey(PublicKey publicKey) {
this.publicKey = publicKey;
}
public interface Callback<T extends ApiResponse> {
void call(T response);
}
public interface Before {
void call(ApiRequest request);
}
public interface After {
void call(ApiRequest request, ApiResponse response);
}
public void setAfter(After after) {
this.after = after;
}
public void setBefore(Before before) {
this.before = before;
}
public <T extends ApiResponse> T execute(ApiRequest<T> request, boolean isEnhanced, ProgressRequestBody.ProgressListener listener) {
if (before != null) {
before.call(request);
}
// 检查请求参数
T t = MapperUtil.toJava("{}", request.responseClass());
if (isEnhanced && publicKey == null) {
t.addError(ErrorType.BUSINESS_ERROR, "publicKey can not be null.");
}
if (t.hasError()) {
return t;
}
try {
//装载请求参数
String currentTime = String.valueOf(System.currentTimeMillis());
RequestBody requestBody = new MultipartBody.Builder()
.addFormDataPart(P_APP_KEY, appKey)
.addFormDataPart("isEnhanced", "false")
.addFormDataPart("encryptData", null, ProgressRequestBody.createProgressRequestBody(encode(request, isEnhanced), listener))
.addFormDataPart(P_TIMESTAMP, currentTime)
.addFormDataPart(P_SIGN, sign(request, currentTime))
.addFormDataPart(P_ENHANCED, String.valueOf(isEnhanced))
.addFormDataPart(P_TOKEN, token)
.build();
Request build = new Request.Builder()
.url(serverUrl + request.apiMethod())
.post(requestBody)
.build();
Response response = httpClient.newCall(build).execute();
String responseJson = decryptResponse(response, isEnhanced);
t = MapperUtil.toJava(responseJson, request.responseClass());
} catch (ConnectException e) {
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.SYSTEM_ERROR, "网络异常!");
} catch (SocketTimeoutException e) {
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.SYSTEM_ERROR, "请求超时!");
} catch (IOException e) {
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.SYSTEM_ERROR, "请求异常!");
} finally {
if (after != null) {
after.call(request, t);
}
}
return t;
}
public <T extends ApiResponse> void execute(ApiRequest<T> request, Callback callback) {
execute(request, false, callback, null);
}
public <T extends ApiResponse> void execute(final ApiRequest<T> request, final boolean isEnhanced, final Callback callback, ProgressRequestBody.ProgressListener listener) {
if (before != null) {
before.call(request);
}
// 检查请求参数
T t = MapperUtil.toJava("{}", request.responseClass());
if (isEnhanced && publicKey == null) {
t.addError(ErrorType.BUSINESS_ERROR, "publicKey can not be null.");
}
if (t.hasError()) {
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
return;
}
try {
//装载请求参数
String currentTime = String.valueOf(System.currentTimeMillis());
RequestBody requestBody = new FormBody.Builder()
.add(P_APP_KEY, appKey)
.add(P_METHOD, request.apiMethod())
.add(P_TYPE, TYPE_JSON)
// .add(P_TARGET, null, ProgressRequestBody.createProgressRequestBody(encode(request, isEnhanced), listener))
.add(P_TIMESTAMP, currentTime)
.add(P_SIGN, sign(request, currentTime))
.add(P_ENHANCED, String.valueOf(isEnhanced))
.add(P_TOKEN, token)
.build();
Request build = new Request.Builder()
.url(serverUrl + request.apiMethod())
.post(requestBody)
.build();
httpClient.newCall(build).enqueue(new okhttp3.Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
T t = MapperUtil.toJava("{}", request.responseClass());
if (e instanceof ConnectException) {
t.addError(ErrorType.BUSINESS_ERROR, "网络异常!");
} else if (e instanceof SocketTimeoutException) {
t.addError(ErrorType.BUSINESS_ERROR, "请求超时!");
} else {
t.addError(ErrorType.BUSINESS_ERROR, "请求异常!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
}
public void onResponse(Call call, Response response) throws IOException {
T t = null;
try {
String responseJson = decryptResponse(response, isEnhanced);
t = MapperUtil.toJava(responseJson, request.responseClass());
} catch (Exception e) {
e.printStackTrace();
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.BUSINESS_ERROR, "服务器走了下神!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
}
});
} catch (Exception e) {
T baseResponse = MapperUtil.toJava("{}", request.responseClass());
baseResponse.addError(ErrorType.SYSTEM_ERROR, "请求异常!");
if (after != null) {
after.call(request, baseResponse);
}
if (callback != null) {
callback.call(baseResponse);
}
}
}
public void fileUpload(final FileUploadRequest request, final Callback<FileUploadResponse> callback, ProgressRequestBody.ProgressListener listener) {
if (before != null) {
before.call(request);
}
try {
//检查文件是否存在
if (!request.isExist()) {
FileUploadResponse fileUploadResponse = new FileUploadResponse();
fileUploadResponse.addError(ErrorType.BUSINESS_ERROR, "文件不存在!");
if (after != null) {
after.call(request, fileUploadResponse);
}
callback.call(fileUploadResponse);
return;
}
//装载请求参数
String currentTime = String.valueOf(System.currentTimeMillis());
MultipartBody.Builder builder = new MultipartBody.Builder()
.addFormDataPart(P_APP_KEY, appKey)
.addFormDataPart(P_METHOD, request.apiMethod())
.addFormDataPart(P_TYPE, TYPE_FILE)
.addFormDataPart(P_TIMESTAMP, currentTime)
.addFormDataPart(P_SIGN, sign(request, currentTime))
.addFormDataPart(P_TOKEN, token);
if (request.getFile() != null) {
builder.addFormDataPart(P_TARGET, request.getFile().getName(), ProgressRequestBody.createProgressRequestBody(MediaType.parse("image/*"), request.getFile(), listener));
builder.addFormDataPart(P_FILE_NAME, request.getFileName());
} else {
builder.addFormDataPart(P_TARGET, null, ProgressRequestBody.createProgressRequestBody(Base64Util.encodeToString(request.getBytes()), listener));
builder.addFormDataPart(P_FILE_NAME, request.getFileName());
}
MultipartBody multipartBody = builder.build();
Request build = new Request.Builder()
.url(serverUrl)
.post(multipartBody)
.build();
httpClient.newCall(build).enqueue(new okhttp3.Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
FileUploadResponse t = MapperUtil.toJava("{}", FileUploadResponse.class);
if (e instanceof ConnectException) {
t.addError(ErrorType.BUSINESS_ERROR, "网络异常!");
} else if (e instanceof SocketTimeoutException) {
t.addError(ErrorType.BUSINESS_ERROR, "请求超时!");
} else {
t.addError(ErrorType.BUSINESS_ERROR, "请求异常!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
}
public void onResponse(Call call, Response response) throws IOException {
FileUploadResponse t = null;
try {
String responseJson = decryptResponse(response, false);
t = MapperUtil.toJava(responseJson, FileUploadResponse.class);
} catch (Exception e) {
e.printStackTrace();
t = new FileUploadResponse();
t.addError(ErrorType.BUSINESS_ERROR, "服务器走了下神!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 对请求进行加密编码
*
* @param request
* @return
*/
private String encode(ApiRequest request, boolean isEnhanced) {
String json = MapperUtil.toJson(request);
if (isEnhanced) {
return RSAUtil.encrypt2Base64(json.getBytes());
} else {
return AESUtil.encrypt2Base64(json.getBytes(), appSecret);
}
}
/**
* 对响应进行解密
*
* @param response
* @return
*/
private String decryptResponse(Response response, boolean isEnhanced) throws IOException {
String responseString = response.body().string();
String responseJson;
if (isEnhanced) {
responseJson = RSAUtil.decrypt2String(responseString);
} else {
responseJson = AESUtil.decrypt2String(responseString, appSecret);
}
if (debug) {
System.out.println("加密响应结果:" + responseString);
System.out.println("响应结果:" + responseJson);
}
return responseJson;
}
/**
* 对请求进行签名
*
* @param request
* @return
*/
private String sign(ApiRequest request, String currentTime) {
if (request instanceof FileUploadRequest) {//文件签名、对文件字节生成的信息摘要签名
FileUploadRequest fileUploadRequest = (FileUploadRequest) request;
String encode = MD5Util.encode(fileUploadRequest.getFile() != null ? toByteArray(fileUploadRequest.getFile()) : fileUploadRequest.getBytes());
return MD5Util.encode(appSecret + encode + currentTime);
} else {//普通参数签名、此处JSON是经过排序生成的JSON字符串,因此验签时也需要排序
String json = MapperUtil.toJson(request);
return MD5Util.encode(appSecret + json + currentTime);
}
}
public static byte[] toByteArray(File file) {
File f = file;
if (!f.exists()) {
return null;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(f));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
return null;
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void setTokenId(String token) {
this.token = token;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
}

@ -2,11 +2,12 @@ package ${domain};
import okhttp3.*; import okhttp3.*;
import java.io.*; import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.security.PublicKey;
public class ApiClient { public class ApiClient {
private static ApiClient ourInstance = null; private static ApiClient ourInstance = null;
@ -26,36 +27,16 @@ public class ApiClient {
return ourInstance; return ourInstance;
} }
//基本请求参数KEY
private static final String P_APP_KEY = "app_key";
private static final String P_TYPE = "type";
private static final String P_TARGET = "target";
private static final String P_FILE_NAME = "file_name";
private static final String P_TIMESTAMP = "timestamp";
private static final String P_METHOD = "method";
private static final String P_SIGN = "sign";
private static final String P_TOKEN = "token_id";
private static final String P_ENHANCED = "enhanced";
//参数类型
private static final String TYPE_JSON = "json";
private static final String TYPE_FILE = "file";
//应用码 //应用码
private String appKey; private String appKey;
//应用安全码 //应用安全码
private String appSecret; private String appSecret;
//服务器地址 //服务器地址
private String serverUrl; private String serverUrl;
//公钥
private PublicKey publicKey = null;
private OkHttpClient httpClient = null; private OkHttpClient httpClient = null;
//默认参数 //默认参数
private static final int DEFAULT_CONNECT_TIMEOUT = 3;//秒 private static final int DEFAULT_CONNECT_TIMEOUT = 5;//秒
private static final int DEFAULT_READ_TIMEOUT = 30;//秒 private static final int DEFAULT_READ_TIMEOUT = 10;//秒
//请求配置
private int connectTimeout;//3秒
private int readTimeout;//30秒
private boolean needCheckRequest = true; // 是否在客户端校验请求
private boolean needEnableParser = true; // 是否对响应结果进行解释
private Before before = null; private Before before = null;
private After after = null; private After after = null;
@ -63,8 +44,6 @@ public class ApiClient {
private boolean debug = false; private boolean debug = false;
private ApiClient(String serverUrl, String appKey, String appSecret, int connectTimeout, int readTimeout) { private ApiClient(String serverUrl, String appKey, String appSecret, int connectTimeout, int readTimeout) {
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
this.appKey = appKey; this.appKey = appKey;
this.appSecret = appSecret; this.appSecret = appSecret;
this.serverUrl = serverUrl; this.serverUrl = serverUrl;
@ -74,10 +53,6 @@ public class ApiClient {
.build(); .build();
} }
public void setPublicKey(PublicKey publicKey) {
this.publicKey = publicKey;
}
public interface Callback<T extends ApiResponse> { public interface Callback<T extends ApiResponse> {
void call(T response); void call(T response);
} }
@ -98,31 +73,33 @@ public class ApiClient {
this.before = before; this.before = before;
} }
public <T extends ApiResponse> T execute(ApiRequest<T> request, boolean isEnhanced, ProgressRequestBody.ProgressListener listener) { public <T extends ApiResponse> T execute(ApiRequest<T> request) {
return execute(request, null);
}
public <T extends ApiResponse> T execute(ApiRequest<T> request, ProgressRequestBody.ProgressListener listener) {
if (before != null) { if (before != null) {
before.call(request); before.call(request);
} }
if (debug) {
System.out.println("debug-->请求内容:" + MapperUtil.toJson(request));
}
// 检查请求参数 // 检查请求参数
T t = MapperUtil.toJava("{}", request.responseClass()); T t = MapperUtil.toJava("{}", request.responseClass());
if (isEnhanced && publicKey == null) {
t.addError(ErrorType.BUSINESS_ERROR, "publicKey can not be null.");
}
if (t.hasError()) {
return t;
}
try { try {
//装载请求参数 //装载请求参数
String currentTime = String.valueOf(System.currentTimeMillis()); String currentTime = String.valueOf(System.currentTimeMillis());
String base64 = AESUtil.encrypt2Base64(MapperUtil.toJson(request).getBytes(), appSecret);
RequestBody requestBody = new MultipartBody.Builder() RequestBody requestBody = new MultipartBody.Builder()
.addFormDataPart(P_APP_KEY, appKey) .addFormDataPart("appKey", appKey)
.addFormDataPart("isEnhanced", "false") .addFormDataPart("encryptData", null, ProgressRequestBody.createProgressRequestBody(base64, listener))
.addFormDataPart("encryptData", null, ProgressRequestBody.createProgressRequestBody(encode(request, isEnhanced), listener)) .addFormDataPart("sign", sign(request, currentTime))
.addFormDataPart(P_TIMESTAMP, currentTime) .addFormDataPart("timestamp", currentTime)
.addFormDataPart(P_SIGN, sign(request, currentTime)) .addFormDataPart("token", token)
.addFormDataPart(P_ENHANCED, String.valueOf(isEnhanced))
.addFormDataPart(P_TOKEN, token)
.build(); .build();
Request build = new Request.Builder() Request build = new Request.Builder()
@ -131,17 +108,30 @@ public class ApiClient {
.build(); .build();
Response response = httpClient.newCall(build).execute(); Response response = httpClient.newCall(build).execute();
String responseJson = decryptResponse(response, isEnhanced); if (response.isSuccessful()) {
String responseString = response.body().string();
String responseJson = null;
if (!responseString.startsWith("{")) {
if (debug) System.out.println("debug-->加密响应结果:" + responseString);
responseJson = AESUtil.decrypt2String(responseString, appSecret);
if (debug) System.out.println("debug-->响应结果:" + responseJson);
} else {
responseJson = responseString;
if (debug) System.out.println("debug-->响应结果:" + responseJson);
}
t = MapperUtil.toJava(responseJson, request.responseClass()); t = MapperUtil.toJava(responseJson, request.responseClass());
} else if (404 == response.code()) {
t.addError(ErrorType.SYSTEM_ERROR, "地址不存在!");
} else if (403 == response.code()) {
t.addError(ErrorType.SYSTEM_ERROR, "禁止访问!");
} else if (500 == response.code()) {
t.addError(ErrorType.SYSTEM_ERROR, "服务器走了下神!");
}
} catch (ConnectException e) { } catch (ConnectException e) {
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.SYSTEM_ERROR, "网络异常!"); t.addError(ErrorType.SYSTEM_ERROR, "网络异常!");
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.SYSTEM_ERROR, "请求超时!"); t.addError(ErrorType.SYSTEM_ERROR, "请求超时!");
} catch (IOException e) { } catch (IOException e) {
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.SYSTEM_ERROR, "请求异常!"); t.addError(ErrorType.SYSTEM_ERROR, "请求异常!");
} finally { } finally {
if (after != null) { if (after != null) {
@ -151,226 +141,26 @@ public class ApiClient {
return t; return t;
} }
public <T extends ApiResponse> void execute(ApiRequest<T> request, Callback callback) { public <T extends ApiResponse> void executeCall(ApiRequest<T> request, Callback callback) {
execute(request, false, callback, null); ExecutorService executorService = Executors.newFixedThreadPool(1);
} executorService.execute(new Runnable() {
@Override
public <T extends ApiResponse> void execute(final ApiRequest<T> request, final boolean isEnhanced, final Callback callback, ProgressRequestBody.ProgressListener listener) { public void run() {
if (before != null) { T execute = execute(request, null);
before.call(request); callback.call(execute);
}
// 检查请求参数
T t = MapperUtil.toJava("{}", request.responseClass());
if (isEnhanced && publicKey == null) {
t.addError(ErrorType.BUSINESS_ERROR, "publicKey can not be null.");
}
if (t.hasError()) {
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
return;
}
try {
//装载请求参数
String currentTime = String.valueOf(System.currentTimeMillis());
RequestBody requestBody = new FormBody.Builder()
.add(P_APP_KEY, appKey)
.add(P_METHOD, request.apiMethod())
.add(P_TYPE, TYPE_JSON)
// .add(P_TARGET, null, ProgressRequestBody.createProgressRequestBody(encode(request, isEnhanced), listener))
.add(P_TIMESTAMP, currentTime)
.add(P_SIGN, sign(request, currentTime))
.add(P_ENHANCED, String.valueOf(isEnhanced))
.add(P_TOKEN, token)
.build();
Request build = new Request.Builder()
.url(serverUrl + request.apiMethod())
.post(requestBody)
.build();
httpClient.newCall(build).enqueue(new okhttp3.Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
T t = MapperUtil.toJava("{}", request.responseClass());
if (e instanceof ConnectException) {
t.addError(ErrorType.BUSINESS_ERROR, "网络异常!");
} else if (e instanceof SocketTimeoutException) {
t.addError(ErrorType.BUSINESS_ERROR, "请求超时!");
} else {
t.addError(ErrorType.BUSINESS_ERROR, "请求异常!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
}
public void onResponse(Call call, Response response) throws IOException {
T t = null;
try {
String responseJson = decryptResponse(response, isEnhanced);
t = MapperUtil.toJava(responseJson, request.responseClass());
} catch (Exception e) {
e.printStackTrace();
t = MapperUtil.toJava("{}", request.responseClass());
t.addError(ErrorType.BUSINESS_ERROR, "服务器走了下神!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
} }
}); });
} catch (Exception e) {
T baseResponse = MapperUtil.toJava("{}", request.responseClass());
baseResponse.addError(ErrorType.SYSTEM_ERROR, "请求异常!");
if (after != null) {
after.call(request, baseResponse);
}
if (callback != null) {
callback.call(baseResponse);
}
}
} }
public <T extends ApiResponse> void executeCall(ApiRequest<T> request, Callback callback, ProgressRequestBody.ProgressListener listener) {
public void fileUpload(final FileUploadRequest request, final Callback<FileUploadResponse> callback, ProgressRequestBody.ProgressListener listener) { ExecutorService executorService = Executors.newFixedThreadPool(1);
if (before != null) { executorService.execute(new Runnable() {
before.call(request); @Override
} public void run() {
T execute = execute(request, listener);
try { callback.call(execute);
//检查文件是否存在
if (!request.isExist()) {
FileUploadResponse fileUploadResponse = new FileUploadResponse();
fileUploadResponse.addError(ErrorType.BUSINESS_ERROR, "文件不存在!");
if (after != null) {
after.call(request, fileUploadResponse);
}
callback.call(fileUploadResponse);
return;
}
//装载请求参数
String currentTime = String.valueOf(System.currentTimeMillis());
MultipartBody.Builder builder = new MultipartBody.Builder()
.addFormDataPart(P_APP_KEY, appKey)
.addFormDataPart(P_METHOD, request.apiMethod())
.addFormDataPart(P_TYPE, TYPE_FILE)
.addFormDataPart(P_TIMESTAMP, currentTime)
.addFormDataPart(P_SIGN, sign(request, currentTime))
.addFormDataPart(P_TOKEN, token);
if (request.getFile() != null) {
builder.addFormDataPart(P_TARGET, request.getFile().getName(), ProgressRequestBody.createProgressRequestBody(MediaType.parse("image/*"), request.getFile(), listener));
builder.addFormDataPart(P_FILE_NAME, request.getFileName());
} else {
builder.addFormDataPart(P_TARGET, null, ProgressRequestBody.createProgressRequestBody(Base64Util.encodeToString(request.getBytes()), listener));
builder.addFormDataPart(P_FILE_NAME, request.getFileName());
}
MultipartBody multipartBody = builder.build();
Request build = new Request.Builder()
.url(serverUrl)
.post(multipartBody)
.build();
httpClient.newCall(build).enqueue(new okhttp3.Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
FileUploadResponse t = MapperUtil.toJava("{}", FileUploadResponse.class);
if (e instanceof ConnectException) {
t.addError(ErrorType.BUSINESS_ERROR, "网络异常!");
} else if (e instanceof SocketTimeoutException) {
t.addError(ErrorType.BUSINESS_ERROR, "请求超时!");
} else {
t.addError(ErrorType.BUSINESS_ERROR, "请求异常!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
}
public void onResponse(Call call, Response response) throws IOException {
FileUploadResponse t = null;
try {
String responseJson = decryptResponse(response, false);
t = MapperUtil.toJava(responseJson, FileUploadResponse.class);
} catch (Exception e) {
e.printStackTrace();
t = new FileUploadResponse();
t.addError(ErrorType.BUSINESS_ERROR, "服务器走了下神!");
}
if (after != null) {
after.call(request, t);
}
if (callback != null) {
callback.call(t);
}
} }
}); });
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
*
* @param request
* @return
*/
private String encode(ApiRequest request, boolean isEnhanced) {
String json = MapperUtil.toJson(request);
if (isEnhanced) {
return RSAUtil.encrypt2Base64(json.getBytes());
} else {
return AESUtil.encrypt2Base64(json.getBytes(), appSecret);
}
}
/**
*
*
* @param response
* @return
*/
private String decryptResponse(Response response, boolean isEnhanced) throws IOException {
String responseString = response.body().string();
String responseJson;
if (isEnhanced) {
responseJson = RSAUtil.decrypt2String(responseString);
} else {
responseJson = AESUtil.decrypt2String(responseString, appSecret);
}
if (debug) {
System.out.println("加密响应结果:" + responseString);
System.out.println("响应结果:" + responseJson);
}
return responseJson;
} }
/** /**
@ -380,42 +170,9 @@ public class ApiClient {
* @return * @return
*/ */
private String sign(ApiRequest request, String currentTime) { private String sign(ApiRequest request, String currentTime) {
if (request instanceof FileUploadRequest) {//文件签名、对文件字节生成的信息摘要签名
FileUploadRequest fileUploadRequest = (FileUploadRequest) request;
String encode = MD5Util.encode(fileUploadRequest.getFile() != null ? toByteArray(fileUploadRequest.getFile()) : fileUploadRequest.getBytes());
return MD5Util.encode(appSecret + encode + currentTime);
} else {//普通参数签名、此处JSON是经过排序生成的JSON字符串,因此验签时也需要排序
String json = MapperUtil.toJson(request); String json = MapperUtil.toJson(request);
return MD5Util.encode(appSecret + json + currentTime); return MD5Util.encode(appSecret + json + currentTime);
} }
}
public static byte[] toByteArray(File file) {
File f = file;
if (!f.exists()) {
return null;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(f));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
return null;
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void setTokenId(String token) { public void setTokenId(String token) {
this.token = token; this.token = token;
@ -429,3 +186,4 @@ public class ApiClient {
this.debug = debug; this.debug = debug;
} }
} }

@ -11,7 +11,7 @@ public interface ApiRequest<T extends ApiResponse> {
void check(); void check();
String apiMethod(); String path();
Class<T> responseClass(); Class<T> responseClass();
} }

@ -1,105 +0,0 @@
package ${domain};
import ${domain}.request.*;
import ${domain}.response.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* ApiTest - 测试用例
*
* @author author
* @version 0.0.1
* @since 2019-06-11
*/
public class ApiTest {
private ApiClient apiClient;
@Before
public void before() {
//实例化API请求客户端
ApiClient.init("http://localhost:8080/api", "app_key", "1234567890123456");
apiClient = ApiClient.getInstance();
ApiClient client = ApiClient.getInstance();
// 以下为对称加密公钥,对重要关键请求加密,可不设
String cryptPublicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTrwfsrJjCF+pP4S3A/wrD4U1txg53EuBC1mPt" +
"3vGXvSK2U0YNRVR3Q65ooHnPKmk4LwI8v+7+ATTxUg3qkuRiDuzBa5zLkYKM50LOgEWSdOKzbnbx" +
"a5FnE7IXawNt1p8+MVN1TTI7J/fZy6g1x0WBy1odE5Osru4WfZNOqQtjHwIDAQAB";
client.setPublicKey(RSAUtil.parsePublicKey(cryptPublicKeyBase64));
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
//设置发送网络请求前的统一操作
client.setBefore(new ApiClient.Before() {
public void call(ApiRequest request) {
System.out.println("请求参数" + MapperUtil.toJson(request));
System.out.println("请求方法" + request.apiMethod());
}
});
//设置网络请求完成后的统一操作
client.setAfter(new ApiClient.After() {
public void call(ApiRequest request, ApiResponse response) {
System.out.println("响应参数" + MapperUtil.toJson(response));
Date end = new Date();
System.out.println(simpleDateFormat.format(end));
}
});
}
@Test
public void testFileUpload() {
{//无进度显示
final Date start = new Date();
//文件上传请求
FileUploadRequest fileUploadRequest = new FileUploadRequest();
fileUploadRequest.setFile(new File("D:\\1.PNG"));
apiClient.fileUpload(fileUploadRequest, new ApiClient.Callback<FileUploadResponse>() {
public void call(FileUploadResponse response) {
Date end = new Date();
System.out.println("无进度显示" + (end.getTime() - start.getTime()));
}
});
}
{//有进度显示
final Date start = new Date();
//文件上传请求
FileUploadRequest fileUploadRequest = new FileUploadRequest();
fileUploadRequest.setFile(new File("D:\\1.PNG"));
apiClient.fileUpload(fileUploadRequest, new ApiClient.Callback<FileUploadResponse>() {
public void call(FileUploadResponse response) {
Date end = new Date();
System.out.println("有进度显示" + (end.getTime() - start.getTime()));
}
}, new ProgressRequestBody.ProgressListener() {
public void onProgress(long totalBytes, long remainingBytes, boolean done) {
System.out.println((totalBytes - remainingBytes) * 100 / totalBytes + "%");
}
});
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
<#list apiList as item>
@Test
public void test${item.targetRequest}() {
${item.targetRequest} request = new ${item.targetRequest}();
${item.targetResponse} response = apiClient.execute(request);
Assert.assertTrue(!response.hasError());
}
</#list>
}

@ -0,0 +1,59 @@
package ${domain};
import ${domain}.request.*;
import ${domain}.response.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* ApiTest -
*
* @author author
* @version 0.0.1
* @since 2019-06-11
*/
public class ApiTest {
private ApiClient apiClient;
@Before
public void before() {
//实例化API请求客户端
ApiClient.init("http://localhost:8080/api", "app_key", "1234567890123456");
apiClient = ApiClient.getInstance();
ApiClient client = ApiClient.getInstance();
client.setDebug(true);
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
//设置发送网络请求前的统一操作
client.setBefore(new ApiClient.Before() {
public void call(ApiRequest request) {
System.out.println("请求参数" + MapperUtil.toJson(request));
System.out.println("请求方法" + request.apiMethod());
}
});
//设置网络请求完成后的统一操作
client.setAfter(new ApiClient.After() {
public void call(ApiRequest request, ApiResponse response) {
System.out.println("响应参数" + MapperUtil.toJson(response));
Date end = new Date();
System.out.println(simpleDateFormat.format(end));
}
});
}
<#list apiList as item>
@Test
public void test${item.targetRequest}() {
${item.targetRequest} request = new ${item.targetRequest}();
${item.targetResponse} response = apiClient.execute(request);
Assert.assertTrue(!response.hasError());
}
</#list>
}

@ -1,59 +0,0 @@
package ${domain};
import java.io.File;
/**
* FileUploadRequest - 文件上传请求
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class FileUploadRequest implements ApiRequest<FileUploadResponse> {
private String fileName;
private File file;
private byte[] bytes;
public void setFile(File file) {
this.file = file;
this.fileName = file.getName();
this.bytes = null;
}
public void setFile(byte[] bytes, String fileName) {
this.bytes = bytes;
this.fileName = fileName;
this.file = null;
}
public boolean isExist() {
if ((file != null && file.exists()) || bytes != null) {
return true;
}
return false;
}
public File getFile() {
return file;
}
public byte[] getBytes() {
return bytes;
}
public String getFileName() {
return fileName;
}
public void check() {
}
public String apiMethod() {
return "api.file.upload";
}
public Class<FileUploadResponse> responseClass() {
return FileUploadResponse.class;
}
}

@ -1,67 +0,0 @@
package ${domain};
/**
* FileUploadResponse - 文件上传响应
*
* @author wangbing
* @version 0.0.1
* @since 2017-01-01
*/
public class FileUploadResponse extends ApiResponse {
/**
* 文件ID
*/
private Long id;
/**
* url地址
*/
private String url;
private String attribute1;
private String attribute2;
private String attribute3;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAttribute1() {
return attribute1;
}
public void setAttribute1(String attribute1) {
this.attribute1 = attribute1;
}
public String getAttribute2() {
return attribute2;
}
public void setAttribute2(String attribute2) {
this.attribute2 = attribute2;
}
public String getAttribute3() {
return attribute3;
}
public void setAttribute3(String attribute3) {
this.attribute3 = attribute3;
}
}

@ -1,259 +0,0 @@
package ${domain}.action;
import ${domain}.${module}.mgr.*;
import ${domain}.${module}.req.*;
import ${domain}.frame.base.BaseResponse;
import ${domain}.frame.base.ErrorType;
import ${domain}.frame.base.Token;
import ${domain}.frame.utils.*;
import org.springframework.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Controller
public class ApiController {
//基本请求参数KEY
private static final String P_APP_KEY = "app_key";
private static final String P_TYPE = "type";
private static final String P_TARGET = "target";
private static final String P_TARGET_JSON = "target_json";
private static final String P_FILE_NAME = "file_name";
private static final String P_TIMESTAMP = "timestamp";
private static final String P_METHOD = "method";
private static final String P_SIGN = "sign";
private static final String P_ENHANCED = "enhanced";
//安全模式,签名或加密
private static final String MODE_SIGN = "sign";
private static final String MODE_ENCRYPTION = "encryption";
//参数类型
private static final String TYPE_JSON = "json";
private static final String TYPE_FILE = "file";
//签名方式
private static final String SIGN_METHOD_MD5 = "MD5";
private static final String SIGN_METHOD_RSA = "RSA";
//加密方式
private static final String ENCRYPTION_METHOD_MD5 = "MD5";
private static final String ENCRYPTION_METHOD_RSA = "RSA";
private static final String APP_SECRET = "1234567890123456";
<#list managerList as i>
@Autowired
private ${tool.abb2Abb(i)} ${tool.Abb2abb(i)};
</#list>
@RequestMapping("/api")
@ResponseBody
public String api(HttpServletRequest request) {
BaseResponse baseResponse = new BaseResponse();
//安全认证
validate(request, baseResponse);
//权限认证
if (!baseResponse.hasError()) {
authenticate(request, baseResponse);
}
// 业务处理
if (!baseResponse.hasError()) {
baseResponse = handle(request);
}
return encrypt(request,baseResponse);
}
private String encrypt(HttpServletRequest request,BaseResponse baseResponse){
String enhanced = request.getParameter(P_ENHANCED);
boolean isEnhanced = !StringUtils.isEmpty(enhanced) && "true".equals(enhanced);
byte[] bytes = MapperUtil.toJson(baseResponse).getBytes();
if (isEnhanced){
return RSAUtil.encrypt2Base64(bytes);
}else {
return AESUtil.encrypt2Base64(bytes, APP_SECRET);
}
}
/**
* 请求处理器
*
* @param request
* @return
*/
private BaseResponse handle(HttpServletRequest request) {
//File请求处理
if (TYPE_FILE.equals(request.getParameter(P_TYPE))) {
return handleFILE(request);
}
//JSON请求处理
if (TYPE_JSON.equals(request.getParameter(P_TYPE))) {
return handleJSON(request);
}
BaseResponse baseResponse = new BaseResponse();
baseResponse.addError(ErrorType.BUSINESS_ERROR, "请求未处理");
return baseResponse;
}
/**
* 上传文件请求处理
*
* @param request
* @return
*/
private BaseResponse handleFILE(HttpServletRequest request) {
BaseResponse baseResponse = new BaseResponse();
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
String fileName = multipartHttpServletRequest.getParameter(P_FILE_NAME);
byte[] data = null;
try {
MultipartFile target = multipartHttpServletRequest.getFile(P_TARGET);
if (target == null) {
String base64 = multipartHttpServletRequest.getParameter(P_TARGET);
data = Base64Util.decode(base64);
} else {
data = target.getBytes();
}
} catch (IOException e) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "文件获取失败!");
return baseResponse;
}
//========
//处理文件
//========
if (data != null) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "文件上传成功,但未处理文件[" + fileName + "]!");
}else {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "文件上传失败!");
}
return baseResponse;
}
private BaseResponse handleJSON(HttpServletRequest request){
BaseResponse baseResponse = new BaseResponse();
String method = null;
String targetJson = null;
try {
method = request.getParameter(P_METHOD);
targetJson = (String) request.getAttribute(P_TARGET_JSON);
if (method == null) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "请求方法不能为空!");
return baseResponse;
}
if (targetJson == null) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "请求目标不能为空!");
return baseResponse;
}
switch (method) {
<#list methodList as m >
case "${m.stringMethod}":
baseResponse = ${m.target}${tool.abb2Abb(m.method)}(targetJson, LocalData.getToken());
break;
</#list>
default:
baseResponse.addError(ErrorType.INVALID_PARAMETER, Message.NOT_EXIST_METHOD);
break;
}
} catch (Exception ex) {
baseResponse.addError(ErrorType.SYSTEM_ERROR, Message.ERROR_500);
LogUtil.dumpException(ex);
} finally {
if (baseResponse.hasError()) {
LogUtil.e("请求方法:" + method + ", 请求目标:" + targetJson);
LogUtil.e("错误原因:" + MapperUtil.toJson(baseResponse.getErrors()));
}
}
return baseResponse;
}
/**
* 安全认证
*
* @param request
* @return
*/
private void validate(HttpServletRequest request, BaseResponse baseResponse) {
String type = request.getParameter(P_TYPE);
String timestamp = request.getParameter(P_TIMESTAMP);
String sign = request.getParameter(P_SIGN);
String enhanced = request.getParameter(P_ENHANCED);
boolean isEnhanced = !StringUtils.isEmpty(enhanced) && "true".equals(enhanced);
if(type == null || timestamp == null || sign == null){
baseResponse.addError(ErrorType.BUSINESS_ERROR,"无效参数");
return;
}
if (TYPE_JSON.equals(type)) {
String target = request.getParameter(P_TARGET);
String jsonString = null;
try {
if (isEnhanced) {
jsonString = RSAUtil.decrypt2String(target);
} else {
jsonString = AESUtil.decrypt2String(target, APP_SECRET);
}
}catch (Exception e){
baseResponse.addError(ErrorType.BUSINESS_ERROR,"Target解码错误,请确认编码是否正确!");
return;
}
String sign_ = MD5Util.encode(APP_SECRET + jsonString + timestamp);
if (!sign_.equals(sign)) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "签名验证失败");
}
request.setAttribute(P_TARGET_JSON,jsonString);
} else if (TYPE_FILE.equals(type)) {
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multipartHttpServletRequest.getFile(P_TARGET);
String base64 = multipartHttpServletRequest.getParameter(P_TARGET);
try {
String sign_ = MD5Util.encode(APP_SECRET + MD5Util.encode(file != null ? file.getBytes() : Base64Util.decode(base64)) + timestamp);
if (!sign_.equals(sign)) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "签名验证失败");
}
} catch (IOException e) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "签名验证失败");
}
return;
}
if (!baseResponse.hasError()){//时效性验证
long timestamp_ = Long.parseLong(timestamp);
long currentTime = System.currentTimeMillis();
if (currentTime - timestamp_ > 2 * 60 * 1000) {
baseResponse.addError(ErrorType.BUSINESS_ERROR, "请求过期, 或本地时间错误.");
}
}
}
private void authenticate(HttpServletRequest request, BaseResponse baseResponse){
Token token = new Token();
token.setId(0L);
token.setUserId(0L);
token.setUserName("admin");
LocalData.setToken(token);
}
<#list methodList as m>
private BaseResponse ${m.target}${tool.abb2Abb(m.method)}(String targetJson, Token token) {
${m.request} request = MapperUtil.toJava(targetJson, ${m.request}.class);
return ${m.manager}.${m.method}(request, token);
}
</#list>
}

@ -1,10 +0,0 @@
package ${domain}.${module}.enums;
<#list annotation as i>
${i}
</#list>
public enum ${className} {
<#list body as i>
${i}
</#list>
}

@ -3,7 +3,10 @@ package ${basePackage}.action;
import ${basePackage}.config.ActionConfig; import ${basePackage}.config.ActionConfig;
import ${basePackage}.frame.auth.LocalData; import ${basePackage}.frame.auth.LocalData;
import ${basePackage}.frame.base.*; import ${basePackage}.frame.base.*;
import ${basePackage}.frame.utils.*; import ${basePackage}.frame.utils.AESUtil;
import ${basePackage}.frame.utils.LogUtil;
import ${basePackage}.frame.utils.MD5Util;
import ${basePackage}.frame.utils.MapperUtil;
import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.core.TreeNode;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -285,49 +288,64 @@ public class GlobalController implements ErrorController {
} }
} }
@RequestMapping("/api/{module}/{target}/{method}")
@RequestMapping(path = "/api/{module}/{target}/{method}", method = RequestMethod.POST)
@ResponseBody @ResponseBody
public String api( public String api(
@PathVariable String module, @PathVariable String module,
@PathVariable String target, @PathVariable String target,
@PathVariable String method, @PathVariable String method,
@RequestParam String sign, @RequestParam(required = false) String appKey,
@RequestParam boolean isEnhanced, @RequestParam(required = false) String sign,
@RequestParam long timestamp, @RequestParam(required = false) Long timestamp,
@RequestParam String encryptData) { @RequestParam(required = false) Long token,
BaseResponse response = new BaseResponse();; @RequestParam(required = false) String encryptData) {
BaseResponse response = new BaseResponse();
if (appKey == null) {
response.addError(ErrorType.BUSINESS_ERROR, "应用码参数[appKey]不存在!");
return MapperUtil.toJson(response);
} else if (sign == null) {
response.addError(ErrorType.BUSINESS_ERROR, "签名参数[sign]不存在!");
return MapperUtil.toJson(response);
} else if (timestamp == null) {
response.addError(ErrorType.BUSINESS_ERROR, "时间戳参数[timestamp]不存在!");
return MapperUtil.toJson(response);
}
String data = null; String data = null;
String appSecret = "1234567890123456"; String appSecret = "1234567890123456";
// 解码 // 解码
try { try {
if (isEnhanced) {
data = RSAUtil.decrypt2String(encryptData);
} else {
data = AESUtil.decrypt2String(encryptData, appSecret); data = AESUtil.decrypt2String(encryptData, appSecret);
} } catch (Exception e) {
}catch (Exception e){ response.addError(ErrorType.BUSINESS_ERROR, "解码失败,请确认编码是否正确!");
response.addError(ErrorType.BUSINESS_ERROR,"解码失败,请确认编码是否正确!"); return MapperUtil.toJson(response);
} }
// 验证签名 // 验证签名
String sign_ = MD5Util.encode(appSecret + data + timestamp); String sign_ = MD5Util.encode(appSecret + data + timestamp);
if (!sign_.equals(sign)) { if (!sign_.equals(sign)) {
response.addError(ErrorType.BUSINESS_ERROR, "签名验证失败!"); response.addError(ErrorType.BUSINESS_ERROR, "签名验证失败!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
} }
// 时效性验证 // 时效性验证
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
if (currentTime - timestamp > 2 * 60 * 1000) { if (currentTime - timestamp > 2 * 60 * 1000) {
response.addError(ErrorType.BUSINESS_ERROR, "请求过期, 或本地时间错误!"); response.addError(ErrorType.BUSINESS_ERROR, "请求过期, 或本地时间错误!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
} }
// 实例化Token // 权限验证 todo 模拟权限验证
Token token = new Token(); {
token.setId(0L); Token tokenPO = new Token();
token.setUserId(0L); tokenPO.setId(token != null ? token : 0L);
token.setUserName("admin"); tokenPO.setUserId(0L);
LocalData.setToken(token); tokenPO.setUserName("admin");
LocalData.setToken(tokenPO);
}
// 开始处理业务
try { try {
String beanClassName = (ActionConfig.API_PREFIX + module + "/" + target).toLowerCase(); String beanClassName = (ActionConfig.API_PREFIX + module + "/" + target).toLowerCase();
Object ajax = LocalData.getApplicationContext().getBean(beanClassName); Object ajax = LocalData.getApplicationContext().getBean(beanClassName);
@ -343,6 +361,7 @@ public class GlobalController implements ErrorController {
if (methodC == null) { if (methodC == null) {
response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的方法!"); response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的方法!");
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
} }
Parameter[] parameters = methodC.getParameters(); Parameter[] parameters = methodC.getParameters();
@ -368,16 +387,8 @@ public class GlobalController implements ErrorController {
e.getTargetException().printStackTrace(); e.getTargetException().printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "方法执行错误[" + e.getTargetException().getMessage() + "]"); response.addError(ErrorType.BUSINESS_ERROR, "方法执行错误[" + e.getTargetException().getMessage() + "]");
} }
return AESUtil.encrypt2Base64(MapperUtil.toJson(response).getBytes(), appSecret);
// 返回加密内容
byte[] bytes = MapperUtil.toJson(response).getBytes();
if (isEnhanced) {
return RSAUtil.encrypt2Base64(bytes);
} else {
return AESUtil.encrypt2Base64(bytes, appSecret);
} }
}
private static ConcurrentHashMap<String, SseEmitter> sseMap = new ConcurrentHashMap(); private static ConcurrentHashMap<String, SseEmitter> sseMap = new ConcurrentHashMap();

Loading…
Cancel
Save

Powered by TurnKey Linux.