HandlerMethodArgumentResolver(パラメータ解析器)の役割+使用事例

4469 ワード

前言
今日、プロジェクトをしている間に、パラメータ解析に関するHandlerMethodArgumentResolverの使用に関する疑問に遭遇しました.初心者の私はここで皆さんと交流して記録したいと思います.これから発車・・・
本文
 
まず、このインタフェース、HandlerMethodArgumentResolverを認識してみましょう.
public interface HandlerMethodArgumentResolver {
    boolean supportsParameter(MethodParameter var1);

    Object resolveArgument(MethodParameter var1, ModelAndViewContainer var2, NativeWebRequest var3, WebDataBinderFactory var4) throws Exception;
}

このインタフェースには、supportsParameterとresolveArgumentの2つの方法があります.
メソッドsupportsParameterはよく理解され、戻り値はbooleanタイプであり、Controllerレイヤのパラメータが条件を満たすかどうかを判断し、条件を満たすとresolveArgumentメソッドを実行し、満たさないとスキップする役割を果たす.
resolveArgumentメソッドは、supportsParameterメソッドがtrueを返す場合にのみ呼び出されます.いくつかのビジネスを処理するために、戻り値をControllerレイヤのこのパラメータに割り当てます.
したがって,HandlerMethodArgumentResolverをパラメータ解析器として理解することができ,クラス実装HandlerMethodArgumentResolverインタフェースを書くことでController層におけるメソッドパラメータの修正を実現することができる.
プロジェクトコードの例
パラメータ解析器が使用されていない場合のControllerコントローラ:
@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";
    }
}

皆さんよく見てくださいto_loginメソッドのこの2つのパラメータcookieTokenとparamTokenを、メソッドボディをもう一度よく見てみましょう.この2つのパラメータとメソッドボディの文コードは、クッキーまたはrequestのtokenという変数によってユーザーuserの情報をクエリーするためであることがわかります.
しかし、皆さんは発見していません.この方法は、簡単なこの小さな機能のために、こんなに多くのコードを書いています.ちょっと太りすぎじゃないですか?また、ユーザーuserという情報変数を使用する他の方法はありますか?
はい、この時、HandlerMethodArgumentResolverインタフェースを使用して小さな最適化を行うことができます.
HandlerMethodArgumentResolver解析を使用した後:
クラス実装を書くHandlerMethodArgumentResolverインタフェース

@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
	@Autowired
	MiaoshaUserService userService;
	public boolean supportsParameter(MethodParameter parameter) {
		Class> clazz = parameter.getParameterType();
		return clazz==MiaoshaUser.class;
	}
	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);

		String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);
		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();
		for(Cookie cookie : cookies) {
			if(cookie.getName().equals(cookiName)) {
				return cookie.getValue();
			}
		}
		return null;
	}
}

私たちが作成したこのクラスをプロファイルに登録します.
@Configuration
public class WebConfig  extends WebMvcConfigurerAdapter{
	@Autowired
	UserArgumentResolver userArgumentResolver;
	@Override
	public void addArgumentResolvers(List argumentResolvers) {
		argumentResolvers.add(userArgumentResolver);
	}
}

最後に、私たちの制御クラスはこのように書くことができます.
    @RequestMapping("/to_list")
    public String list(Model model,MiaoshaUser user) {
    	model.addAttribute("user", user);
    	//      
    	List goodsList = goodsService.listGoodsVo();
    	model.addAttribute("goodsList", goodsList);
        return "goods_list";
    }