赞
踩
今天在做项目时遇到了一个有关参数解析HandlerMethodArgumentResolver的使用疑惑。我想作为新手的我在此和大家一起交流并记录。接下来开始发车......
首先先来认识一下这个接口,HandlerMethodArgumentResolver。
- public interface HandlerMethodArgumentResolver {
- boolean supportsParameter(MethodParameter var1);
-
- Object resolveArgument(MethodParameter var1, ModelAndViewContainer var2, NativeWebRequest var3, WebDataBinderFactory var4) throws Exception;
- }
大家可以看到,这个接口有两个方法,supportsParameter和resolveArgument。
方法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方法的这两个参数 cookieToken和paramToken,再仔细看一下方法体。不难看出,这两个参数和方法体中的语句代码就是为了,通过cookie或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<HandlerMethodArgumentResolver> argumentResolvers) {
- argumentResolvers.add(userArgumentResolver);
- }
- }
最后,我们的控制类就可以这样写了
- @RequestMapping("/to_list")
- public String list(Model model,MiaoshaUser user) {
- model.addAttribute("user", user);
- //查询商品列表
- List<GoodsVo> goodsList = goodsService.listGoodsVo();
- model.addAttribute("goodsList", goodsList);
- return "goods_list";
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。