SpringMVC自定義引數解析器
阿新 • • 發佈:2021-08-17
一、問題描述
前端把 token 存放在請求頭裡面,後端介面如果需要獲取當前登入使用者資訊,我們是使用 HttpServletRequest 來獲取請求頭的 token,但是如果後續很多介面都需要獲取當前登入使用者資訊,此時就出現程式碼重複問題。
二、假設分析
我們能不能做出一個介面引數,讓所有訪問這個具備指定引數的介面都能獲取當前登入使用者物件,該怎麼實現?
三、應用技術
使用技術:SpringMVC 引數解析器
解析器有兩種:
- SpringMVC 預設解析器
- 自定義引數解析器
作用:將介面(請求對映方法)UserInfo 型別的引數解析成當前登入使用者物件
這兩種,選哪個呢?不難看出,因為預設引數解析器是無法實現當前登入使用者物件注入,此時選擇第二種。
四、程式碼實現
業務需要區分場景的時候(比如登入與未登入),可以編寫一個自定義註解
編寫一個自定義註解,放於 annotation 包下
@Target(ElementType.PARAMETER) // 引數
@Retention(RetentionPolicy.RUNTIME)
public @interface UserParam {
}
新建一個 resolver 包,編寫自定義解析器
/** * 自定義引數解析器 * 作用: * 將介面中宣告 UserInfo 型別的引數,解析成當前登入使用者物件,並注入 */ public class UserInfoArgumentResolver implements HandlerMethodArgumentResolver { @Autowired private IUserInfoRedisService userInfoRedisService; //用於識別介面引數型別 //指定當前解析器能解析介面引數的型別: 此處是UserInfo.class型別 @Override public boolean supportsParameter(MethodParameter methodParameter) { return methodParameter.getParameterType() == UserInfo.class && methodParameter.hasParameterAnnotation(UserParam.class); } //用於解析介面引數,並注入引數值 //前提: 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"); UserInfo userInfo = userInfoRedisService.getUserByToken(token); return userInfo; } }
配置類
@Configuration public class WebsiteConfig implements WebMvcConfigurer { // 引數解析器 @Bean public UserInfoArgumentResolver userInfoArgumentResolver(){ return new UserInfoArgumentResolver(); } // 加進 HandlerMethodArgumentResolver 裡面作為它的實現類 @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(userInfoArgumentResolver()); } }
controller層
@GetMapping("/userInfo")
@ResponseBody
public Object user(@UserParam UserInfo user){
return JsonResult.success(user);
}
以上,程式碼已實現功能
那麼,SpringMVC 的自定義引數解析器究竟是如何實現功能的呢?看流程圖