HandlerMethodArgumentResolver(参数解析器)的作用+使用小案例

前言

今天在做项目时遇到了一个有关参数解析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";
    }

 

 

HandlerMethodArgumentResolverSpring MVC中的一个接口,用于解决方法参数代入参数值在给定请求的上下文中的问题。它可以将请求中的参数值转换为方法参数类型,并将其注入到方法中。以下是HandlerMethodArgumentResolver使用方法: 1.创建一个类实现HandlerMethodArgumentResolver接口,并实现supportsParameter和resolveArgument方法。supportsParameter方法用于判断该解析器是否支持该参数类型,resolveArgument方法用于将请求中的参数值转换为方法参数类型。 2.在Spring MVC配置文件中配置HandlerMethodArgumentResolver,将其添加到RequestMappingHandlerAdapter中。 下面是一个简单的例子,演示如何使用HandlerMethodArgumentResolver: ```java // 自定义参数解析器 public class UserArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterType().equals(User.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); String username = request.getParameter("username"); String password = request.getParameter("password"); User user = new User(username, password); return user; } } // 在Spring MVC配置文件中配置HandlerMethodArgumentResolver @Configuration @EnableWebMvc public class AppConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new UserArgumentResolver()); } } // 控制器方法 @RequestMapping("/login") public String login(User user) { // 处理登录逻辑 return "success"; } ``` 在上面的例子中,我们创建了一个UserArgumentResolver类,用于将请求中的参数值转换为User对象,并将其注入到login方法中。然后在Spring MVC配置文件中配置了UserArgumentResolver,并将其添加到RequestMappingHandlerAdapter中。最后,在login方法中,我们可以直接使用User对象,而不需要手动解析请求参数
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值