函数泛型参数反序列化

反序列化

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;
    }
}
posted @ 2025-05-29 17:35  fight139  阅读(10)  评论(0)    收藏  举报