1. 程式人生 > >通過重寫HandlerMethodArgumentResolver來定義控制層引數的傳遞規則

通過重寫HandlerMethodArgumentResolver來定義控制層引數的傳遞規則

1.先看一段程式碼

這段程式碼的引數顯得很冗餘,而且在控制層間傳遞pojo類每次需要寫這麼多引數。

package com.example.miaosha_xdp.controller;

import com.alibaba.druid.util.StringUtils;
import com.example.miaosha_xdp.VO.UserVo;
import com.example.miaosha_xdp.entity.User;
import com.example.miaosha_xdp.exception.GlobalException;
import com.example.miaosha_xdp.result.CodeMsg;
import com.example.miaosha_xdp.result.Result;
import com.example.miaosha_xdp.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;


@Controller
@RequestMapping("/goods")
public class GoodsController {
    private static Logger logger = LoggerFactory.getLogger(GoodsController.class);
    @Autowired
    UserService userService;

    @RequestMapping("/to_list")
    public String to_login(Model model,HttpServletResponse response,@CookieValue(value =UserService.TOKEN,required = false)String cookieToken,
                                        @RequestParam(value = UserService.TOKEN,required = false) String paramToken) {
        if(StringUtils.isEmpty(cookieToken)&&StringUtils.isEmpty(paramToken)){
            return "login";
        }
        String token = StringUtils.isEmpty(cookieToken) ? paramToken : cookieToken;
        User user=userService.getByToken(response,token);
        logger.info(user.toString());
        model.addAttribute("user",user);
        return "goods_list";
    }


}

2.重新HandlerMethodArgumentResolver

為了解決這個問題,我們來重新springMVC裡面的MethodArgumentResolver

package com.example.miaosha_xdp.config;

import com.example.miaosha_xdp.entity.User;
import com.example.miaosha_xdp.redis.MiaoshaUserKey;
import com.example.miaosha_xdp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Period;

/**
 * HandlerMethodArgumentResolver是SpringMVC中,給控制層方法的引數賦值的
 * 先根據引數型別尋找引數,如果有該型別,就賦值給這個引數
 */
@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
    @Autowired
    UserService userService;

    /**
     * 定義要賦值的引數型別
     *
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Class<?> clazz = methodParameter.getParameterType();
        return clazz == User.class;
    }

    /**
     * 具體執行賦值的方法
     *
     * @param methodParameter
     * @param modelAndViewContainer
     * @param nativeWebRequest
     * @param webDataBinderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        //獲取request和response
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
        //分別在request的引數中和cookie中查詢我們的需要的token
        String paramToken = request.getParameter(UserService.TOKEN);
        String cokieToken = getCookieToken(request, UserService.TOKEN);

        String token = StringUtils.isEmpty(paramToken) ? cokieToken : paramToken;
        return userService.getByToken(response,token);
    }

    private String getCookieToken(HttpServletRequest request, String key) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(UserService.TOKEN)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}

3.把我們編寫的處理類註冊到配置中

package com.example.miaosha_xdp.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Autowired
    UserArgumentResolver userArgumentResolver;

    /**
     * 新增我們到處理器到配置中
     * @param argumentResolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
       argumentResolvers.add(userArgumentResolver);
    }
}

4.這樣我們最開始的程式碼就變了類下面的

 

package com.example.miaosha_xdp.controller;


import com.example.miaosha_xdp.entity.User;
import com.example.miaosha_xdp.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
@RequestMapping("/goods")
public class GoodsController {
    private static Logger logger = LoggerFactory.getLogger(GoodsController.class);
    @Autowired
    UserService userService;

    @RequestMapping("/to_list")
    public String to_login(Model model,User user) {
        model.addAttribute("user",user);
        return "goods_list";
    }
    
}