HandlerMethodArgumentResolver简介


一、HandlerMethodArgumentResolver简介

直接看源码

/**
 * 解析处理方法参数的类
 */
public interface HandlerMethodArgumentResolver {

	/**
	 * 该方法的参数是否需要处理
	 */
	boolean supportsParameter(MethodParameter parameter);

	/**
	 * 真正解析处理方法参数的地方
	 */
	@Nullable
	Object 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 {

	@Override
	public 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.
	 */
	@Override
	public 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 {
    @Autowired
    private 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 {

    @Autowired
    private RequestUserCodeArgumentResolver requestUserCodeArgumentResolver;


    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(requestUserCodeArgumentResolver);
    }

    /**
    * 功能描述: 处理swagger不展示的问题
    */
    @Override
    protected 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());
        }
    }

总结

你的项目中有没有类似的需求呢,或者遇到一些问题用这种方式处理的话会更好,那就赶快动手试一下吧

				欢迎打击关注我的微信公众号,您的关注就是我不懈的动力

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
HandlerMethodArgumentResolverSpring框架提供的一个接口,用于解析方法参数。它的作用是将请求中的参数值绑定到方法的参数上,使得方法能够正确地获取到请求中的数据。 HandlerMethodArgumentResolver接口定义了一个方法resolveArgument,该方法用于解析方法参数。具体的解析逻辑由实现了HandlerMethodArgumentResolver接口的类来实现。Spring框架提供了一些默认的实现类,如RequestParamMethodArgumentResolver和PathVariableMethodArgumentResolver。 RequestParamMethodArgumentResolver用于解析@RequestParam注解修饰的方法参数,它会根据请求中的参数名和方法参数名进行匹配,并将匹配到的参数值绑定到方法参数上。 PathVariableMethodArgumentResolver用于解析@PathVariable注解修饰的方法参数,它会根据请求中的路径变量和方法参数名进行匹配,并将匹配到的路径变量值绑定到方法参数上。 下面是一个使用HandlerMethodArgumentResolver的示例代码: ```java @RestController public class UserController { @GetMapping("/user/{id}") public User getUser(@PathVariable("id") Long id) { // 根据id查询用户信息 User user = userService.getUserById(id); return user; } } ``` 在上述代码中,getUser方法使用了@PathVariable注解修饰的id参数。当请求路径为"/user/123"时,PathVariableMethodArgumentResolver会将路径中的123绑定到id参数上,从而获取到对应的用户信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值