HandlerMethodArgumentResolver解析与使用

HandlerMethodArgumentResolver详解

一、前言

最近在项目中看到的一个接口,之前没见过这个写法,记录一下。

二、源码

源码不长,直接拷贝吧。

/**
 * Strategy interface for resolving method parameters into argument values in
 * the context of a given request.
 *
 * @author Arjen Poutsma
 * @since 3.1
 * @see HandlerMethodReturnValueHandler
 */
public interface HandlerMethodArgumentResolver {

	/**
	 * Whether the given {@linkplain MethodParameter method parameter} is
	 * supported by this resolver.
	 * @param parameter the method parameter to check
	 * @return {@code true} if this resolver supports the supplied parameter;
	 * {@code false} otherwise
	 */
	boolean supportsParameter(MethodParameter parameter);

	/**
	 * Resolves a method parameter into an argument value from a given request.
	 * A {@link ModelAndViewContainer} provides access to the model for the
	 * request. A {@link WebDataBinderFactory} provides a way to create
	 * a {@link WebDataBinder} instance when needed for data binding and
	 * type conversion purposes.
	 * @param parameter the method parameter to resolve. This parameter must
	 * have previously been passed to {@link #supportsParameter} which must
	 * have returned {@code true}.
	 * @param mavContainer the ModelAndViewContainer for the current request
	 * @param webRequest the current request
	 * @param binderFactory a factory for creating {@link WebDataBinder} instances
	 * @return the resolved argument value, or {@code null} if not resolvable
	 * @throws Exception in case of errors with the preparation of argument values
	 */
	@Nullable
	Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

}

通过官方的讲解,我们可以知道,这个接口就是将请求参数解析成特定类型的策略接口。

需要实现两个方法:

1、supportsParameter: 判断请求参数是否支持此解析器
2、resolveArgument: 做参数解析的具体实现方法

参数说明:

MethodParameter parameter:要解析的方法参数,这个参数必须是支持该解析器的

ModelAndViewContainer mavContainer: 当前请求的 ModelAndViewContainer 容器

NativeWebRequest webRequest:当前的 请求实体

WebDataBinderFactory binderFactory:实例创建工厂

返回值: 具体的需要解析的对象

三、实现

简单看看该策略接口都有哪些具体的实现吧。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1sTlCnXP-1637808887888)(C:\Users\lurious\AppData\Roaming\Typora\typora-user-images\image-20211125095956664.png)]

简单看了下,有几个我们比较常用的参数

PathVariableMethodArgumentResolver //  @PathParam 注解解析器
RequestHeaderMethodArgumentResolver // @RequestHeader 注解解析器
RequestParamMethodArgumentResolver // @RequestParam 注解解析器

四、应用

在开发中常常需要获取登录用户的信息,如果每次都去写解析方法的话 可能会有点麻烦,

这个时候就可以直接自定义一个参数解析器,专门用来解析登录用户的信息。

这里拷贝人人开源里的一个例子来做示例

@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Autowired
    private UserService userService;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        //获取用户ID
        Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
        if(object == null){
            return null;
        }

        //获取用户信息
        UserEntity user = userService.getById((Long)object);

        return user;
    }
}

逻辑比较简单,判断注解是否合法,然后从注解中拿到用户ID信息,再从数据库拿数据就可以。对于比较复杂的场景,这可能是有用的。

最后别忘了再webMvcConfig中添加解析器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       ........
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值