【Spring】自定义argumentResolver参数解析器 解决用户ID问题


【Spring】自定义argumentResolver参数解析器 解决用户ID问题

项目环境:Spring + Spring MVC + Spring Security + 其他

 

最近开发系统的过程中,有一些控制器方法会要求客户端传入userID值。

一开始在JS中获取LocalStorage里存的userId提交,存在被伪造请求的可能。

由于框架使用的是Spring Security,可以通过Principal直接获取用户信息,所以考虑到安全性,不由用户携带用户ID提交请求,而是转为服务器主动获取用户ID。

SecurityContext sc = SecurityContextHolder.getContext(); Authentication auth = sc.getAuthentication(); LoginUser loginUser = (LoginUser) auth.getPrincipal(); Integer userId = loginUser.getId();

 

但每次都在控制器里加这一段,控制器数量一多后,代码变得不简洁,所以思考能否使用Spring注解来解决。

 

在网上查询资料后,Spring MVC 可以通过注解往函数里添加额外的信息,使得这些被添加注解的数据可以交由框架来处理并赋值。

 

第一步,添加自定义注解,注解名为UserId

/** * @author qinyuguan */ @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface UserId { boolean required() default true; }

 

第二步,写UserId的参数解析器

/** * @author qinyuguan * @date 2020/3/15 17:21 */
public class UserIdMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { if (parameter.getParameterType().equals(Integer.class) && parameter.hasParameterAnnotation(UserId.class)) { return true; } return false; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { UserId currentUserAnnotation = parameter.getParameterAnnotation(UserId.class); SecurityContext sc = SecurityContextHolder.getContext(); Authentication auth = sc.getAuthentication(); LoginUser loginUser = (LoginUser) auth.getPrincipal(); Integer userId = loginUser.getId(); return userId; } }

 

第三步,注册解析器,配置MvcConfig

/** * @author qinyuguan * @date 2020/3/15 17:27 */ @Configuration public class WebAppConfig{ @Bean public WebMvcConfigurer webMvcConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new UserIdMethodArgumentResolver()); } }; } }

 

最后,使用,在控制器里随便写一个方法,在参数里添加一个Id的参数,并为其添加@UserId注解:

 

    @GetMapping("/main") @ResponseBody public Results getInfo(@UserId Integer userId){ System.out.println(userId); return service.getInfo(userId); }

 

测试,是否可用,控制台输出了用户ID。

1001

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM