HandlerMethodArgumentResolver统一获取当前登录用户
场景:前端每次请求都传token,后端封装一方法tokenUtils.getUserByToken(token),根据token解析得到currentUserInfo。
由于是自定义的规则,所以每次都需要手动调用方法获取UserInfo,所以使用拦截器来获取当前登陆用户的信息。
一、自定义权限拦截器
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
private TokenUtils tokenUtils;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
String token = request.getHeader("Authorization");
User user = tokenUtils.getUserByToken(token);
request.setAttribute("CURRENT_USER", user);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
User类
public class User {
private String name;
private String age;
}
TokenUtils
@Component
public class TokenUtils {
public User getUserByToken(String token) {
User user = null;
ObjectMapper objectMapper = new ObjectMapper();
try {
user = objectMapper.readValue(token, User.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return user;
}
}
二、自定义参数注解
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface CurrentUser {
}
三、自定义方法参数解析器
自定义方法参数解析器CurrentUserMethodArgumentResolver,需实现HandlerMethodArgumentResolver。
@Component
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(User.class)
&& parameter.hasParameterAnnotation(CurrentUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
return (User) webRequest.getAttribute("CURRENT_USER",RequestAttributes.SCOPE_REQUEST);
}
}
四、配置MVC
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Autowired
AuthenticationInterceptor authenticationInterceptor;
@Autowired
CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver;
/**
* 参数解析器
*
* @param argumentResolvers
*/
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(currentUserMethodArgumentResolver);
}
/**
* 拦截器规则
*
* @param registry
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**");
super.addResourceHandlers(registry);
}
}
五、测试
@RestController
@Slf4j
public class TestController {
@GetMapping("/interceptor")
public void testInterceptor(@CurrentUser User user) {
log.info("{}",user);
}
}