Springboot中使用自定义参数注解获取 token 中用户数据

时间:2023-11-25 21:14:44

使用自定义参数注解获取 token 中User数据

使用背景

在springboot项目开发中需要从token中获取用户信息时通常的方式要经历几个步骤

  1. 拦截器中截获token
  2. TokenUtil工具类解析token中的用户信息
  3. 把解析结果存入到成员变量中
  4. controller中通过TokenUtil工具类提供的静态方法获取用户信息

下面是过程示例代码

/*--------1.拦截器中获取---------*/
String token =request.getHeader("token") /*--------2.解析---------*/
//如果没过期且有效
if(!TokenUtil.isExpire(token)){
//解析token把结果存入成员变量
TokenUtil.decode(token);
} /*--------3.controller中获取---------*/
User currentUser=TokenUtil.getUser();

看上去也没什么复杂指处,但是如果在每个Controller中都加上一句

User currentUser=TokenUtil.getUser();感觉有些多余(潜意识知道肯定有更简洁的方法能减少这里所写代码)

下面介绍一种使用自定义参数注解的方法简化获取结果

最后预期达到的效果

@{RequestMethod}Mapping(value="path")
public Object methodName(@CurrentUser User user){
//...code
}

正文开始

1. 拦截器中的代码(GlobalInterceptor.java)


public class GlobalInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token=request.getHeader("token");
//判断路径需要拦截
//....code //如果token有效
if(!TokenUtil.isExpire(token)){
User user = TokenUtil.getUser(token);
//我们将解析的用户结果先放入session中
request.getSession().setAttribut("currentUser",user);
} return true;
}
}

2. 注解类 (CurrentUser.java)

@Target({ElementType.PARAMETER})//Annotation所修饰的对象范围:方法参数
@Retention(RetentionPolicy.RUNTIME)//Annotation被保留时间:运行时保留(有效)
@Documented//标记注解:java工具文档化
public @interface CurrentUser { }

3. CurrentUser注解实现类(CurrentUserHandlerMethodArgReslover.java)

public class CurrentUserHandlerMethodArgReslover implements HandlerMethodArgumentResolver {

    /**
* 判断是否支持使用@CurrentUser注解的参数
*/
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
//如果该参数注解有@CurrentUser且参数类型是User
return methodParameter.getParameterAnnotation(CurrentUser.class) != null &&methodParameter.getParameterType() == User.class;
} /**
* 注入参数值
*/
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
//取得HttpServletRequest
HttpServletRequest request= (HttpServletRequest) nativeWebRequest.getNativeRequest();
//取出session中的User
return (User)request.getSession().getAttribute("currentUser");
}
}

4. 在SpringBoot启动类中注册 注解的实现类与拦截器(ServerApplication.java)

@SpringBootApplication
public class ServerApplication extends WebMvcConfigurationSupport { /**
* 启动入口
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class,args);
} @Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers){
//注册@CurrentUser注解的实现类
argumentResolvers.add(new CurrentUserHandlerMethodArgReslover());
} /**
* 注册拦截器
* @param registry
*/
@Override
protected void addInterceptors(InterceptorRegistry registry {
//注册拦截器
registry.addInterceptor(new GlobalInterceptor().addPathPatterns("/*/api/**");
registry.addInterceptor(new TestInterceptor().addPathPatterns("/*/api/test/**");
super.addInterceptors(registry);
}
}

5. 在Controller中使用

@GetMapping(value="/demo/api/testget")
public Object getTest(@CurrentUser User currentUser){
System.out.println(currentUser);
return currentUser;
}

到此就实现了预期的结果,回头看发现虽然多写了不少代码,但是在用的时候还是更加简洁明了,美丽大方(给自己比个❤)

gitbook上预览此文章