Former-commit-id: a48ee6664f4ca8f3b8deb9f554687a999e2158f3
master
wangbing 5 years ago
parent f20efdfae6
commit 39277fee6c

@ -76,7 +76,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>

@ -102,7 +102,7 @@ public class ApiClient {
return execute(request, false);
}
public <T extends ApiResponse> T execute(ApiRequest<T> request, boolean isEnhanced) {
public <T extends ApiResponse> T execute(ApiRequest<T> request, boolean isEnhanced, ProgressRequestBody.ProgressListener listener) {
if (before != null) {
before.call(request);
}
@ -119,19 +119,17 @@ public class ApiClient {
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, encode(request, isEnhanced))
.add(P_TIMESTAMP, currentTime)
.add(P_SIGN, sign(request, currentTime))
.add(P_ENHANCED, String.valueOf(isEnhanced))
.add(P_TOKEN, token)
RequestBody requestBody = new MultipartBody.Builder()
.addFormDataPart(P_APP_KEY, appKey)
.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)
.url(serverUrl + request.apiMethod())
.post(requestBody)
.build();

@ -1,36 +1,29 @@
package ${basePackage}.action;
import ${basePackage}.frame.base.*;
import ${basePackage}.frame.auth.LocalData;
import ${basePackage}.config.ActionConfig;
import ${basePackage}.frame.utils.MapperUtil;
import ${basePackage}.frame.utils.FileUtil;
import ${basePackage}.frame.auth.LocalData;
import ${basePackage}.frame.base.*;
import ${basePackage}.frame.utils.*;
import com.fasterxml.jackson.core.TreeNode;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
@ -292,6 +285,99 @@ public class GlobalController implements ErrorController {
}
}
@RequestMapping("/api/{module}/{target}/{method}")
@ResponseBody
public String api(
@PathVariable String module,
@PathVariable String target,
@PathVariable String method,
@RequestParam String sign,
@RequestParam boolean isEnhanced,
@RequestParam long timestamp,
@RequestParam String encryptData) {
BaseResponse response = null;
String data = null;
String appSecret = "1234567890123456";
// 解码
if (isEnhanced) {
data = RSAUtil.decrypt2String(encryptData);
} else {
data = AESUtil.decrypt2String(encryptData, appSecret);
}
if (data == null) {
response.addError(ErrorType.BUSINESS_ERROR, "解码失败,请确认编码是否正确!");
}
// 验证签名
String sign_ = MD5Util.encode(appSecret + data + timestamp);
if (!sign_.equals(sign)) {
response.addError(ErrorType.BUSINESS_ERROR, "签名验证失败!");
}
// 时效性验证
long currentTime = System.currentTimeMillis();
if (currentTime - timestamp > 2 * 60 * 1000) {
response.addError(ErrorType.BUSINESS_ERROR, "请求过期, 或本地时间错误!");
}
// 实例化Token
Token token = new Token();
token.setId(0L);
token.setUserId(0L);
token.setUserName("admin");
LocalData.setToken(token);
try {
String beanClassName = (ActionConfig.API_PREFIX + module + "/" + target).toLowerCase();
Object ajax = LocalData.getApplicationContext().getBean(beanClassName);
Class ajaxClass = ajax.getClass();
Method[] methods = ajaxClass.getDeclaredMethods();
Method methodC = null;
for (Method meth : methods) {
if (meth.getName().equals(method)) {
methodC = meth;
}
}
if (methodC == null) {
response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的方法!");
}
Parameter[] parameters = methodC.getParameters();
Object[] arg = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (BaseRequest.class.isAssignableFrom(parameter.getType())) {
arg[i] = MapperUtil.toJava(data, parameter.getType());
} else if (parameter.getType() == TreeNode.class) {
arg[i] = MapperUtil.toTree(data);
}
}
response = (BaseResponse) methodC.invoke(ajax, arg);
} catch (BeansException e) {
e.printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "未找到对应的目标!");
} catch (IllegalAccessException e) {
e.printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "方法执必须公开!");
} catch (InvocationTargetException e) {
LogUtil.dumpException(e.getTargetException());
e.getTargetException().printStackTrace();
response.addError(ErrorType.BUSINESS_ERROR, "方法执行错误[" + e.getTargetException().getMessage() + "]");
}
// 返回加密内容
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();
/**

@ -6,9 +6,6 @@ import ${basePackage}.module.${module}.req.*;
import ${basePackage}.module.${module}.rsp.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.List;
public class ${table.getCName()}Api{
@Autowired

@ -6,9 +6,6 @@ import ${basePackage}.module.system.req.*;
import ${basePackage}.module.system.rsp.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.List;
public class DictApi {
@Autowired

@ -6,9 +6,6 @@ import ${basePackage}.module.system.req.*;
import ${basePackage}.module.system.rsp.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.List;
public class DictItemApi {
@Autowired

@ -9,9 +9,6 @@ import ${basePackage}.module.system.req.*;
import ${basePackage}.module.system.rsp.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.net.URLEncoder;
public class FileApi {
@Autowired

@ -35,6 +35,7 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
public static String SCREEN_PREFIX = "/screen/";
public static String CONTROL_PREFIX = "/control/";
public static String AJAX_PREFIX = "/ajax/";
public static String API_PREFIX = "/api/";
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
@ -46,6 +47,7 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
registryScreen(basePackage + ".action.screen", beanDefinitionRegistry);
registryControl(basePackage + ".action.control", beanDefinitionRegistry);
registryAjax(basePackage + ".action.ajax", beanDefinitionRegistry);
registryApi(basePackage + ".action.api", beanDefinitionRegistry);
}
}
@ -122,4 +124,27 @@ public class ActionConfig implements BeanDefinitionRegistryPostProcessor {
});
return classPathBeanDefinitionScanner.scan(basePackage);
}
private int registryApi(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return true;
}
});
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanClassName.endsWith("Api")) {
beanClassName = beanClassName.substring(0, beanClassName.length() - 4);
}
String beamName = beanClassName.replaceAll(basePackage + ".", API_PREFIX).replaceAll("\\.","/").toLowerCase();
LogUtil.i("registry api " + beamName);
return beamName;
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
}
}

@ -55,6 +55,28 @@ public class FileUtil {
}
}
public static byte[] toByteArray(InputStream input, int size) throws IOException {
if(size < 0) {
throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
} else if(size == 0) {
return new byte[0];
} else {
byte[] data = new byte[size];
int offset;
int read;
for(offset = 0; offset < size && (read = input.read(data, offset, size - offset)) != -1; offset += read) {
;
}
if(offset != size) {
throw new IOException("Unexpected read size. current: " + offset + ", expected: " + size);
} else {
return data;
}
}
}
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
Throwable var2 = null;

Loading…
Cancel
Save

Powered by TurnKey Linux.