首页 > 技术文章 > Spring配置ArgumentResolver,统一进行session鉴定

brxHqs 2018-09-27 16:51 原文

一.编写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;

 

推荐阅读