|
|
|
@ -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();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|