昨天查资料,偶然看到了一篇介绍处理分页参数的文章 - 我再也不想写@RequestParam("current")了。
我本来想着处理分页参数不是用封装的方式就可以了吗,但是想着万一人家有更加隐式的方式呢,就点进去看了一下。
果然,里面介绍了一个我没有用过的接口- HandlerMethodArgumentResolver
。
这个类就很有意思,可以拦截接口参数,并修改入参值。
那我们就直接开始。
接口源码
源码非常简单,一看就知道怎么用的了:
java
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter parameter);
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
首先supportsParameter
就是判断接口参数是否需要进行处理,也就是执行resolveArgument
方法。这里的入参MethodParameter
就包含了调用的方法和处理的参数。
resolveArgument
就是对这个入参进行处理,入参就是一堆请求信息,而出参就是对参数的设定值。
举例
我们知道@RequestParam
可以设定默认值,那么对于@RequestBody
该怎样设定默认值呢?可以这样:
java
public class MyHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 只对被@RequestBody注解标记的参数进行默认值注入
return parameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Object value = getValue(parameter, webRequest);
// TODO: modify value
return value;
}
private Object getValue(MethodParameter parameter, NativeWebRequest request) {
// TODO: 从request解析出parameter对应的值
return null;
}
}
使用
当然,我们只定义了一个参数处理器是不够的,SpringBoot并不会直接把这个实现类拿来用,我们还需要手动把实现类添加到处理器列表中:
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new MyHandlerMethodArgumentResolver());
}
}
其他
从WebMvcConfigurer
可以看出,里面其实还有很多的add方法,例如addReturnValueHandlers
就是对应的更改方法返回值。