自定义SpringMVC参数解析器


问题

在维护公司开发的一个项目中,发现很多地方都要获取当前登录用户对象,而且是根据请求头中的token值去redis中获取用户信息,于是就很多地方出现了如下类似的代码

1
2
3
4
5
6
7
8
java复制代码public Object commentAdd(TravelComment comment, HttpServletRequest request){
//根据token获取用户信息
String token = request.getHeader("token");
UserInfo user = userInfoRedisService.getUserByToken(token);

//...其他代码
return JsonResult.success();
}

每次都要写HttpServletRequest request,然后根据请求头中的token去获取当前登录对象,这样就导致了很多地方代码都重复了,要如何解决这种问题呢?

解决方案

在请求映射方法列表声明即可,就可以获取当前登录用户对象,代码如下

1
2
3
4
5
6
java复制代码public Object commentAdd(TravelComment comment, UserInfo userInfo){
UserInfo user = userInfo;

//...其他代码
return JsonResult.success();
}

要如何实现上述操作呢? 那就是自定义SpringMVC的参数解析器来完成这项工作,因为通过现有的SpringMVC自带的参数解析器无法完成我们的需求

创建参数解析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
java复制代码/**
* 将请求映射方法列表中UserInfo类型参数进行解析
* 解析成当前登录用户对象
*/
public class UserInfoArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private IUserInfoRedisService userInfoRedisService;
//判断当前解析器支持解析的参数类型,返回true表示支持意思
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType() == UserInfo.class;
}
//解析器解析规则:
//此处将UserInfo类型参数, 解析成当前登录用户对象。
//当supportsParameter方法返回true时候才执行
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
String token = request.getHeader("token");
return userInfoRedisService.getUserByToken(token);
}
}

将自定义参数解析器添加到Spring容器中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码@Configuration
public class WebConfig implements WebMvcConfigurer{

//自定义的用户解析器
@Bean
public UserInfoArgumentResolver userInfoArgumentResolver(){
return new UserInfoArgumentResolver();
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userInfoArgumentResolver());
}
}

上述的所有操作,确实可以达到我们想要的结果,但是还是存在一些问题,并不是所有的请求映射方法列表中有UserInfo userInfo都要走自定义的参数解析器,那要如何来区分是用框架自带的解析器还是自定义的呢?

使用自定义的注解来区分

在需要使用自定义解析器的请求映射方法列表中添加自定义注解

1
2
3
4
5
6
7
8
java复制代码/**
* 用户参数注入注解
* 贴有该注解用户参数使用自定义的参数解析器
*/
@Target({ElementType.PARAMETER}) //表示贴在参数上
@Retention(RetentionPolicy.RUNTIME)
public @interface UserParam {
}

接口代码改进

1
2
3
4
5
6
java复制代码public Object commentAdd(TravelComment comment, @UserParam UserInfo userInfo){
UserInfo user = userInfo;

//...其他代码
return JsonResult.success();
}

以上就是最终的解决方法!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%