本文主要是介绍HandlerMethodArgumentResolver简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 一、HandlerMethodArgumentResolver简介
- 二、使用步骤(分析@PathVariable )
- 1.自定义注解
- 实现HandlerMethodArgumentResolver接口
- 三、实战演练
- 1.场景
- 2.编写注解
- 3.编写处理参数的类
- 4.注册到spring mvc
- 5.使用
- 总结
一、HandlerMethodArgumentResolver简介
直接看源码
/*** 解析处理方法参数的类*/
public interface HandlerMethodArgumentResolver {/*** 该方法的参数是否需要处理*/boolean supportsParameter(MethodParameter parameter);/*** 真正解析处理方法参数的地方*/@NullableObject resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;}
二、使用步骤(分析@PathVariable )
1.自定义注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {/*** Alias for {@link #name}.*/@AliasFor("name")String value() default "";/*** The name of the path variable to bind to.* @since 4.3.3*/@AliasFor("value")String name() default "";/*** Whether the path variable is required.* <p>Defaults to {@code true}, leading to an exception being thrown if the path* variable is missing in the incoming request. Switch this to {@code false} if* you prefer a {@code null} or Java 8 {@code java.util.Optional} in this case.* e.g. on a {@code ModelAttribute} method which serves for different requests.* @since 4.3.3*/boolean required() default true;}
实现HandlerMethodArgumentResolver接口
/*** Resolves {@link Map} method arguments annotated with an @{@link PathVariable}* where the annotation does not specify a path variable name. The created* {@link Map} contains all URI template name/value pairs.** @author Rossen Stoyanchev* @since 3.2* @see PathVariableMethodArgumentResolver*/
public class PathVariableMapMethodArgumentResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {PathVariable ann = parameter.getParameterAnnotation(PathVariable.class);return (ann != null && Map.class.isAssignableFrom(parameter.getParameterType()) &&!StringUtils.hasText(ann.value()));}/*** Return a Map with all URI template variables or an empty map.*/@Overridepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {@SuppressWarnings("unchecked")Map<String, String> uriTemplateVars =(Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);if (!CollectionUtils.isEmpty(uriTemplateVars)) {return new LinkedHashMap<>(uriTemplateVars);}else {return Collections.emptyMap();}}}
三、实战演练
1.场景
我们在方法参数上经常需要接受用户的信息,比如用户的ID,然后根据用户的ID去数据库查询数据,如果直接拿前台传递的用户ID是不安全的,如果转递的别的用户的ID那么就可以看到别的用户的数据,正确的做法是后台接口中所有的用户信息,都应该获取当前登录的用户的信息(一般用户信息都会放在redis),前台传递的用户信息我们视为不安全的。
2.编写注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface RequestUserCode {
}
3.编写处理参数的类
@Service
public class RequestUserCodeArgumentResolver implements HandlerMethodArgumentResolver {@Autowiredprivate RedisUtil redisUtil;public RequestUserCodeArgumentResolver() {}public boolean supportsParameter(MethodParameter methodParameter) {RequestUserCode annotation = (RequestUserCode)methodParameter.getParameterAnnotation(RequestUserCode.class);return annotation != null;}public String resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {//从redis获取用户信息String id = nativeWebRequest.getHeader("user");if (id != null) {AuthUserInfo authUserInfoObj = this.redisUtil.getAuthUserInfo(id);if (authUserInfoObj != null) {return authUserInfoObj.getUserCode();}}return null;}
}
4.注册到spring mvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {@Autowiredprivate RequestUserCodeArgumentResolver requestUserCodeArgumentResolver;@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {argumentResolvers.add(requestUserCodeArgumentResolver);}/*** 功能描述: 处理swagger不展示的问题*/@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");super.addResourceHandlers(registry);}
}
5.使用
public Result<String> isPermission(@RequestUserCode String userCode) {try {return customerService.permission(customerCode);} catch (OrderException e) {return Result.error(e.getErrorCode(), e.getMsg());}}
总结
你的项目中有没有类似的需求呢,或者遇到一些问题用这种方式处理的话会更好,那就赶快动手试一下吧
欢迎打击关注我的微信公众号,您的关注就是我不懈的动力
这篇关于HandlerMethodArgumentResolver简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!