前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自定义注解(参数解析器)

自定义注解(参数解析器)

原创
作者头像
Java king
发布2023-02-21 15:15:26
6350
发布2023-02-21 15:15:26
举报
文章被收录于专栏:后端Java

对于人类来说,生存本身就是旅行。——东山魁夷

如果咱们的接口,每次开始写之前都需要从token或者cookie中获取用户信息,这种方式虽然可行,但是咱们的代们就会很臃肿。那咱们是不是可以通过某种方式去统一做这些处理呢,而且还保证当我需要的时候才会去获取,不用的时候就不用获取呢,当然这是可以的。咱们可以使用注解HandlerMethodArgumentResolver解析器去完成咱们需要的操作。

首先咱们先介绍一下HandlerMethodArgumentResolver:

HandlerMethodArgumentResolver中文称为方法参数解析器,是Spring Web(SpringMVC)组件中的众多解析器之一,主要用来对Controller中方法的参数进行处理。在一般的接口调用场景下,每次调用Controller都需要检查请求中的token信息,并根据token还原用户信息,然后将用户信息封装到Controller的方法参数中,供方法中接下来的逻辑使用。

代码语言:java
复制
public interface HandlerMethodArgumentResolver {
    boolean supportsParameter(MethodParameter var1);

    @Nullable
    Object resolveArgument(MethodParameter var1, @Nullable ModelAndViewContainer var2, NativeWebRequest var3, @Nullable WebDataBinderFactory var4) throws Exception;
}

咱们通过源码可以看到这个接口里面有两个方法,分别是:supportsParameterresolveArgument

supportsParameter:这个方法很好理解,返回的值是一个boolean类型,它的作用是判断Controller层中的参数,是否满足条件,满足条件则执行resolveArgument方法,不满足则跳过。

resolveArgument:这个方法只有在supportsParameter返回true的情况下才会执行,用于处理一些业务,将返回值赋值咱们需要的参数中。

看到这里是不是大体的思路就有了呢。

1.执行顺序:
  1. 用户请求接口(接口上添加注解)
    1. WebMvcConfigurerAdapter 拦截到转发HandlerMethodArgumentResolver ,执行 supportsParameter
      1. supportsParameter返回true之后调用resolveArgument
        1. resolveArgument进行业务处理返回需要的对象

需要被spring管理且扫面到该配置:

代码语言:java
复制
@Configuration
public class WxWebMvcConfiguration implements WebMvcConfigurer {
	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
		//返回userId
		argumentResolvers.add(new LoginUserHandlerMethodArgumentResolver());
		//返回UserToken
		argumentResolvers.add(new LoginUserRoleHandlerMethodArgumentResolver());
	}
}

首先咱们先自定义一个注解:

代码语言:java
复制

//方法参数上

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

public @interface LoginUserRole {

}

代码语言:txt
复制

注解我就不过多介绍了,可以看我拦截器的这篇文章,这里面有详细讲解自定义注解。我这里要的是放到方法参数上一个注解。

然后咱们新建一个方法实现HandlerMethodArgumentResolver。

并实现HandlerMethodArgumentResolver中的两个方法。

代码语言:java
复制
public class LoginUserRoleHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    public static final String LOGIN_TOKEN_KEY = "Token";

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().isAssignableFrom(UserToken.class) && methodParameter.hasParameterAnnotation(LoginUserRole.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        String token = nativeWebRequest.getHeader(LOGIN_TOKEN_KEY);
        if (token == null || token.isEmpty()) {
            throw new NoLoginException();
        }
        UserToken userToken = UserTokenManager.getRoleId(token);
        if (userToken == null) {
            throw new NoLoginException();
        }
        return userToken;
    }

首先说一下isAssignableFrom():是从类继承的角度去判断,是判断是否为某个类的父类。isAssignableFrom()方法的调用者和参数都是Class对象,调用者为父类,参数为本身或者其子类。

然后就可以根据Header的token解析出来咱们需要的值,然后并返回出去。

代码语言:java
复制
@LoginUserRole UserToken userToken

然后咱们的接口就可以通过在方法前注入咱们自定义的接口,就可以拿到咱们需要的值。这样的话就不用每次都写一遍获取token对象的操作,大大节省了咱们的代码量。让咱们的代码更加简洁。

积极向上:祝大家中秋节快乐。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.执行顺序:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档