您好,登录后才能下订单哦!
本篇内容主要讲解“SpringMVC中的HandlerMethodArgumentResolver接口实现自定义参数类型解析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringMVC中的HandlerMethodArgumentResolver接口实现自定义参数类型解析”吧!
HandlerMethodArgumentResolver
接口看起来很陌生,实际上在SpringMVC中很多地方我们都会直接或者间接的接触到
例如:
@RequestParam
解析 RequestParamMethodArgumentResolver
(基础类型的默认解析器)
@PathVariable
解析 PathVariableMethodArgumentResolver
@RequestBody
解析 RequestResponseBodyMethodProcessor
@CookieValue
解析 ServletCookieValueMethodArgumentResolver
...
通过查看SpringMVC的源码, 可以看到以下代码片段,这就是SpringMVC初始化时,默认的所有HandlerMethodArgumentResolver实现
// org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); // Annotation-based argument resolution resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new PathVariableMapMethodArgumentResolver()); resolvers.add(new MatrixVariableMethodArgumentResolver()); resolvers.add(new MatrixVariableMapMethodArgumentResolver()); resolvers.add(new ServletModelAttributeMethodProcessor(false)); resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice)); resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory())); resolvers.add(new RequestHeaderMapMethodArgumentResolver()); resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory())); resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); resolvers.add(new SessionAttributeMethodArgumentResolver()); resolvers.add(new RequestAttributeMethodArgumentResolver()); // Type-based argument resolution resolvers.add(new ServletRequestMethodArgumentResolver()); resolvers.add(new ServletResponseMethodArgumentResolver()); resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); resolvers.add(new RedirectAttributesMethodArgumentResolver()); resolvers.add(new ModelMethodProcessor()); resolvers.add(new MapMethodProcessor()); resolvers.add(new ErrorsMethodArgumentResolver()); resolvers.add(new SessionStatusMethodArgumentResolver()); resolvers.add(new UriComponentsBuilderMethodArgumentResolver()); // Custom arguments if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } // Catch-all resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); resolvers.add(new ServletModelAttributeMethodProcessor(true)); return resolvers; }
HandlerMethodArgumentResolver
接口就两个方法,一个用来判断是否支持参数类型,一个是解析的具体实现
public interface HandlerMethodArgumentResolver { // 返回是否支持该参数 boolean supportsParameter(MethodParameter parameter); // 返回解析后的参数值 @Nullable Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception; }
这个接口主要的使用场景就是来实现自定义的参数注入。例如在很多前后端分离的项目中,我们不会去使用Session,而是自己维护一个token来实现状态管理,
这种时候,如果需要取得用户数据,正常操作,我们可能需要手动去取得token,然后去查询用户数据
例如以下这个例子,我们从Header中取得token数据,然后从Redis中查询到用户标识,接着从数据库查询到用户基本信息
@PostMapping("get-user-info") public UserInfo getUserInfo(@RequestHeader String token) { // 伪代码 Long userId = redisClient.get(token); UserInfo useInfo = userDao.getById(userId); return userInfo; }
这样写没什么问题,不过在实际的项目中,我们可能很多地方都需要用到用户的一些基本信息,每次都这样去手动编码去取,就显得得很繁琐了
我们使用HandlerMethodArgumentResolver
接口来实现
// 1. 实现HandlerMethodArgumentResolver接口 public class UserInfoArgumentResolver implements HandlerMethodArgumentResolver{ private final RedisClient redisClient; private final UserDao userDao; public UserInfoArgumentResolver(RedisClient redisClient, UserDao userDao) { this.redisClient = redisClient; this.userDao = userDao; } @Override public boolean supportsParameter(MethodParameter parameter) { return UserInfo.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HttpServletRequest nativeRequest = (HttpServletRequest) webRequest.getNativeRequest(); String token = nativeRequest.getHeader("token"); Long userId = redisClient.get(token); UserInfo useInfo = userDao.getById(userId); return userInfo; } } // 2. 添加到配置中 @Configuration @EnableWebMvc public class FastMvcConfiguration implements WebMvcConfigurer { @Autowrite UserDao userDao; @Autowrite RedisClient redisClient; @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new UserInfoArgumentResolver(redisClient, userDao)); } } // 3. 在Controller中使用 @RestController public class UserInfoController { @PostMapping("get-user-info") public UserInfo getUserInfo(UserInfo userInfo) { return userInfo; } @PostMapping("say-hello") public String sayHello(UserInfo userInfo) { return "hello " + userInfo.getNickName(); } }
添加了 UserInfoArgumentResolver
解释器以后,当我们需要使用UserInfo
时,只需要使用指定的类型就可以取得,不需要做其他任何操作
到此,相信大家对“SpringMVC中的HandlerMethodArgumentResolver接口实现自定义参数类型解析”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。