反序列化
private final SecurityProperties securityProperties;
private final ObjectMapper objectMapper;
private Map<String, JavaType> CLASS_CACHE = new HashMap<>();
@ApiOperation(value = "sb通用测试接口", notes = "sb通用测试接口")
@PostMapping("test")
public ApiResult test(@RequestParam String bean, @RequestParam String method,
@RequestParam(required = false) List<String> paramTypes, @RequestBody List<Object> args,
HttpServletRequest request)
throws Exception {
// 强行校验
validateUser(request);
// 基础校验
ServiceAssert.hasText(bean, "bean不能为空");
ServiceAssert.hasText(method, "method不能为空");
ServiceAssert.collectionHasValue(args, "参数列表不能为空");
try {
Object service = SpringUtil.getBean(Class.forName(bean));
List<JavaType> resolvedParamTypes = resolveParamTypes(paramTypes); // 统一解析参数类型
Class[] list = new Class[resolvedParamTypes.size()];
for (int i = 0; i < resolvedParamTypes.size(); i++) {
list[i] = resolvedParamTypes.get(i).getRawClass();
}
Method targetMethod = service.getClass().getMethod(method, list);
Object[] convertedArgs = convertArgs(targetMethod, args, resolvedParamTypes); // 统一参数转换
Object result = targetMethod.invoke(service, convertedArgs);
return ApiResult.success(result);
}
catch (Exception e) {
throw new RuntimeException("反射调用失败", e); // 包装异常信息
}
}
private void validateUser(HttpServletRequest request)
throws Exception {
String encodePwd = request.getParameter("e_pwd");
String pwd = RSAUtil.decrypt(encodePwd, securityProperties.getPrivateKey());
boolean matches = pwd.equals(request.getParameter("pwd"));
ServiceAssert.isTrue(matches, "禁止访问");
}
private JavaType resolveJavaType(String strType, List<String> generalTypes) throws Exception {
// 获取原始类
Class<?> rawClass = Class.forName(strType);
// 处理非泛型类型
if (generalTypes == null || generalTypes.isEmpty()) {
return objectMapper.getTypeFactory().constructType(rawClass);
}
// 处理泛型类型
JavaType[] javaTypes = new JavaType[generalTypes.size()];
for (int j = 0; j < generalTypes.size(); j++) {
// 递归解析泛型参数
javaTypes[j] = resolveJavaType(generalTypes.get(j), Collections.emptyList());
}
// 构造最终类型
return objectMapper.getTypeFactory()
.constructParametricType(rawClass, javaTypes);
}
// 解析参数类型列表
private List<JavaType> resolveParamTypes(List<String> typeNames) throws Exception {
if (typeNames == null) {
return new ArrayList<>();
};
return typeNames.stream().filter(Objects::nonNull).map(type -> CLASS_CACHE.computeIfAbsent(type, i -> {
String[] paramArr = i.split("<");
String strType = paramArr[0];
List<String> generalTypes = new ArrayList<>();
if (paramArr.length > 1) {
generalTypes = Arrays.asList(paramArr[1].replace(">", "").split(","));
}
Class<?> rawClass;
try {
rawClass = Class.forName(strType);
if (!generalTypes.isEmpty()) {
JavaType[] javaTypes = new JavaType[generalTypes.size()];
for (int j = 0; j < generalTypes.size(); j++) {
javaTypes[j] = resolveJavaType(generalTypes.get(j), null);
}
// 构造最终类型
JavaType targetType = objectMapper.getTypeFactory().constructParametricType(rawClass, javaTypes);
return targetType;
}
return objectMapper.getTypeFactory().constructParametricType(rawClass, new Class[0]);
}
catch (Exception e) {
throw new RuntimeException(e);
}
})).collect(Collectors.toList());
}
// 修改convertArgs方法
private Object[] convertArgs(Method method, List<Object> rawArgs, List<JavaType> resolvedParamTypes) throws IOException {
Parameter[] parameters = method.getParameters();
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
// 处理泛型参数
args[i] =
objectMapper.readValue(objectMapper.writeValueAsString(rawArgs.get(i)), resolvedParamTypes.get(i));
}
return args;
}
}