【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