springmvc自定义参数解析器
操作原理
1.当请求进入映射方法之后,发现映射方法声明的形式参数
2.springmvc马上遍历所有参数解析器(包括自定义解析器),一个一个执行supportParameter方法,
一旦返回true,停止循环,表示当前解析器马上调用该解析器resolverArgument方法,
将方法方法返回值注入到形式参数变量中
3.例子,假设映射方法声明一个UserInfo这个参数类型,springmvc执行时候,
发现UserInfoArgumentResolver 解析的supportParameter方法返回true,
那么再调用resolverArgument将当前登录用户信息返回直接注入到userinfo变量中
没用自定义解析器存在问题(代码重复)
存在问题:
后端获取当前登录用户信息使用方法,其他接口要获取当前登录用户对象都需要执行几个步骤
(先获取token,再通过token获取当前登录对象),出现代码重复
直接在请求映射方法中声明UserInfo,这个类型形式参数,springmvc就自动将当前登录用户对象注入
springmvc所有的映射方法中形式参数的值注入都是靠springmvc自带参数解析器实现
现在想要springmvc将当前登录用户对象注入,需要自定义参数解析器
代码(UserArgumentResolver类,核心实现HandlerMethodArgumentResolver接口)
@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private IUserInfoRedisService userInfoRedisService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType() == UserInfo.class
&& methodParameter.hasParameterAnnotation(UserParameter.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter
, ModelAndViewContainer modelAndViewContainer
, NativeWebRequest nativeWebRequest
, WebDataBinderFactory webDataBinderFactory)
throws Exception {
String token = nativeWebRequest.getHeader("token");
UserInfo user = userInfoRedisService.getUserByToken(token);
return user;
}
}
1.将请求映射方法声明形式参数的UserInfo类型的参数,解析成当前登录用户对象并注入
指定该解析器能解析参数类型,返回值为boolean类型,
获取当前登录用户信息对象,并注入UserInfo类型的参数中,当前supportParameter() 返回true时,才执行
2. 在主配置类中,将自定义参数解析器类交给spring容器管理,然后add,将我们自定义的解析器交给springmvc视图解析器
主配置类(哪个服务需要用到自定义参数解析器,哪个服务就要配置这个,不一定是主配置了,只要实现WebMvcConfigurer接口即可)
@SpringBootApplication
public class APP implements WebMvcConfigurer {
@Autowired
private UserArgumentResolver userArgumentResolver;
public static void main(String[] args) {
SpringApplication.run(APP.class, args);
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userArgumentResolver);
}
}
自定义注解(防止都使用自定义注解,所以使用自定义注解来限制)
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserParameter {
}
验证
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/22ae41c4db2085c840187f6b07307c88.png#pic_center)
@GetMapping("/info")
public Object info(@UserParameter UserInfo userInfo) {
return JsonResult.success(userInfo);
}
@GetMapping("/info2")
public Object info2(UserInfo userInfo) {
return JsonResult.success(userInfo);
}
另一种 (获取cookie中的user对象)
public class UserArgumentresolver implements HandlerMethodArgumentResolver {
@Autowired
private RedisService redisService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType() == User.class
&& methodParameter.hasParameterAnnotation(ValidationAnno.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter
, ModelAndViewContainer modelAndViewContainer
, NativeWebRequest nativeWebRequest
, WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
String token = CookieUtil.getToken(request, "userToken");
User user = redisService.get(MemberKeyPrefix.USER_TOKEN, token, User.class);
if (user != null) {
return user;
}
return null;
}
}
小结
springmvc自定义参数解析器可以让我们自定义的注入一些信息,例如:用户信息,开发中经常要获取用户信息,此时我们可以使用自定义参数解析器,然后配合自定义注解,让我们更加方便的获取到用户信息
步骤:
1.实现HandlerMethodArgumentResolver接口,一个方法判断类型,一个方法获取数据并返回
2.将自定义参数解析器交给springmvc管理即可