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";
}
原文链接:https://blog.csdn.net/qq_36408229/article/details/104436508
今天在做项目时遇到了一个有关参数解析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";
}
原文链接:https://blog.csdn.net/qq_36408229/article/details/104436508