为什么要自定义参数解析器呢?
因为很多项目每次获取用户信息,需要重复从请求头中获取token,用token再去redis或是sql中去拿到存储的计本对象,再将获取到的Json数据,转化为我们需要的对象等代码,作为一名程序员面对如此重复的代码实在是不能容忍
当然很多人会说那我将这些步骤封装成一个方法,想要获取的时候调一下不就好了吗。当然这是一个解决办法,但是你依旧需要去在代码中去写对应的方法。
于是我就在想是否可以在接受请求参数的时候就将这些步骤全部执行完毕,Controller接受的时候就已经是一个用户信息的实体类了。
之后我就开始找方法,还真就被我找到了HandlerMethodArgumentResolver.class
,中文称为方法参数解析器,是Spring Web(SpringMVC)组件中的众多解析器之一,主要用来对Controller中方法的参数进行处理。
自定义一个方法参数解析器主要去实现HandlerMethodArgumentResolver.class
中的两个方法:supportsParameter
方法、resolveArgument
方法
-
supportsParameter
方法- 当该方法返回false时,跳过;
- 当该方法返回true时,进入
resolveArgument
方法;
-
resolveArgument
方法- 用于编写request解析逻辑
具体代码
@Component
public class UserInfoArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private RedisService redisService;
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 判断方法参数是否与指定类型对象一致,是则返回true,否则返回false
//如果Controller的接收参数为User类型 返回true
return parameter.getParameterType() == User.class;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest)webRequest.getNativeRequest();
String token = request.getHeader("token");
//通过token去redis中获取数据
String userStr = redisService.getCacheObject(token);
UserInfo userInfo = JSON.parseObject(userStr, UserInfo.class);
User user = JSONUtil.toBean(request.getParameter("user"), User.class);
return user;
}
}
将自定义解析器添加到解析器列表中
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Autowired
private UserInfoArgumentResolver userInfoArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userInfoArgumentResolver);
}
}
Controller
@RequestMapping("/test")
public User test(User user){
return user;
}
不过这个方法有个问题就是多个参数就会报参数类型的错误,我还没找到方法,也希望大家可以试一试