文章目录
场景
对于多个web页面,接口需要取得用户对象user,为了避免多次对用户的查找(如通过token查找)。
解决方案:
- 在interceptor(拦截器)里面解析token拿到用户对象user,然后存入ThreadLocal中;这种就需要我们所有需要用到用户对象user的controller都写一段从ThreadLocal中get的代码;
- 通过一个ArgumentResovler内部解析(查询得到用户对象user的过程),向相应的controller方法的参数中传入一个用户对象user的入参。需要使用注解标注用户对象user参数。
ArgumentResolvers
//WebConfig类
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
UserArgumentResolver userArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(userArgumentResolver);
}
}
将解析的业务逻辑写到resolveArgument方法中
@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
MiaoshaUserService miaoshaUserService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {//设置支持的参数类型
Class<?> clazz=methodParameter.getParameterType();//获取参数类型
return clazz== MiaoshaUser.class;//判断支持的参数类型
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletResponse response=nativeWebRequest.getNativeResponse(HttpServletResponse.class);
HttpServletRequest request=nativeWebRequest.getNativeRequest(HttpServletRequest.class);
String paramToken=request.getParameter(MiaoshaUserService.COOKIE_NAME_TOKEN);
String cookieToken=getCookieValue(request,MiaoshaUserService.COOKIE_NAME_TOKEN);
if(StringUtils.isEmpty(cookieToken)&&StringUtils.isEmpty(paramToken)){
return null;
}
String token=StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
MiaoshaUser user=miaoshaUserService.getByToken(response,token);
return user;
}
private String getCookieValue(HttpServletRequest request, String cookieNameToken) {
Cookie[] cookies=request.getCookies();
for(Cookie cookie:cookies){
if(cookie.getName().equals(cookieNameToken)){
return cookie.getValue();
}
}
return null;
}
}