记一次PathVariable数据处理操作

young 61 2024-11-01

前端请求后端时,会直接使用Id访问接口,Id数据为数据库自增Id,所以这样访问会有数据泄露风险。评估工作量后,决定采用后端返回数据时,对Id进行加密,前端请求使用Id时传输返回的加密数据。

部分接口在获取定义http接口时,采用了路径参数的方式,需要在调用Controller方法前,对数据进行解密。

决定采用HandlerMethodArgumentResolver进行数据操作处理,经查找,Spring中提供了PathVariableMethodArgumentResolver用于处理路径参数,由于并不是所有的路径参数都需要进行处理,故通过自定义注解进行判定。

public class CryptoPathVariableMethodArgumentResolver extends PathVariableMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(PathVariable.class) && parameter.hasParameterAnnotation(IdParameterCrypto.class);
    }

    @Override
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
        Object content = super.resolveName(name, parameter, request);
        IdSecretDto<Object> dto = ParameterCryptoHelper.decodeIdAndCheckUserId((String) content);
        return dto.getId();
    }
}

supportsParameter()用于判断方法是否满足条件

resolveName()PathVariableMethodArgumentResolver提供用于解析地址参数提取出来的数据,将处理后的数据返回,即可正确的提供给调用接口了。

在进行HandlerMethodArgumentResolver的注册时,一开始通过实现WebMvcConfigurer,重写addArgumentResolvers的方法,但是发现采用此种方法注册之后,自定义的HandlerMethodArgumentResolver无法生效。

参考两篇博客后,将注册方式进行修改

@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

@PostConstruct
    public void init() {
        List<HandlerMethodArgumentResolver> argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
        List<HandlerMethodArgumentResolver> list = new ArrayList<>();

        list.add(0, new CryptoPathVariableMethodArgumentResolver());
        list.addAll(argumentResolvers);
        requestMappingHandlerAdapter.setArgumentResolvers(list);
    }

参考:

  1. https://zhuanlan.zhihu.com/p/581486089
  2. https://mp.weixin.qq.com/s?__biz=MzI1MTY1Njk4NQ==&mid=2247506143&idx=1&sn=d2b3e216a64037aa20d4e8e6b7e9eb17&chksm=e9ed36a9de9abfbfcb24d0c10469ade58ec99c721cd3273b50d33475e9ebd6a2afa0409ade5a&token=1230955387&lang=zh_CN#rd