一.编写WebMvcConfig配置类:

重写addArgumentResolvers方法,将解析类加入

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter { @Autowired
UserArgumentResolver userArgumentResolver;//这个解析类,第二步去编写 @Override //用来解析controller的参数类型的,xxx.class的参数可以被用来判断xxx
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(userArgumentResolver);
super.addArgumentResolvers(argumentResolvers);
}
}

二.编写ArgumentResolver解析类:

@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver { @Autowired
MiaoshaUserService userService;//业务逻辑

  @Overrid //判断是否是支持的参数类型
public boolean supportsParameter(MethodParameter parameter) {
Class<?> clazz = parameter.getParameterType();
return clazz==MiaoshaUser.class; //也就是,如果是MiaoshaUser做参数的话,必须得走下面的解析方法
}

  @Overrid //如果是支持的参数类型,调用此方法解析
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
//从传入的参数获取不了内容,那么可以从request入手
MiaoshaUser user = getUser(request,response);
if(user==null){
render(response,CodeMsg.SESSION_ERROR);
}
return user;//返回给controller
} //向浏览器写出json
private void render(HttpServletResponse response, CodeMsg cm)throws Exception {
response.setContentType("application/json;charset=UTF-8");
OutputStream out = response.getOutputStream();
String str = JSON.toJSONString(Result.error(cm));
out.write(str.getBytes("UTF-8"));
out.flush();
out.close();
} //从请求中获取用户信息 封装重复逻辑(统一session鉴定)
private MiaoshaUser getUser(HttpServletRequest request, HttpServletResponse response) {
//尝试从request里取
String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);
//尝试从cookie里取,因为有时cookie禁用了,前端得从request传过来
String cookieToken = getCookieValue(request, MiaoshaUserService.COOKI_NAME_TOKEN);
if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
return null;
}
String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
return userService.getByToken(response, token);
} private String getCookieValue(HttpServletRequest request, String cookiName) {
Cookie[] cookies = request.getCookies();
if(cookies == null || cookies.length <= 0){
return null;
}
for(Cookie cookie : cookies) {
if(cookie.getName().equals(cookiName)) {
return cookie.getValue();
}
}
return null;
}
}

三.修改Controller入口参数类型:

未使用argumentResolver:
@RequestMapping(value="/to_list")
//@ResponseBody
public String list(HttpServletRequest request, HttpServletResponse response, Model model) {
        String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);
//尝试从cookie里取,因为有时cookie禁用了,前端得从request传过来
String cookieToken = getCookieValue(request, MiaoshaUserService.COOKI_NAME_TOKEN);
if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
return null;
}
String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
     //根据token查找从缓存查找user,获取
     MiaoshaUser user = xxxService.getUserByToken(token);
     ......  
修改后:直接传入user:
@RequestMapping(value="/to_list")
//@ResponseBody
public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
// 一般是token,然后对token从redis取user,user为空抛异常跳转(或者给出异常json),这里通过argumentResolver来封装成user;
05-11 22:27