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

使用自定义参数注解获取 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. 注册拦截器(CustomWebMvcConfigurer.java)

@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
            //注册拦截器
            //拦截规则根据实际情况,请做更改 /** 指所有 /*指1级目录
            registry.addInterceptor(new GlobalInterceptor()).addPathPatterns("/*/api/**");
            WebMvcConfigurer.super.addInterceptors(registry);
    }
}

3. 注解类 (CurrentUser.java)

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

}

4. 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");
    }
}

5. 在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());
    }
}

6. 在Controller中使用

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

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

gitbook上预览此文章

原文地址:https://www.cnblogs.com/roseAT/p/11828318.html

时间: 2024-08-10 12:57:28

Springboot中使用自定义参数注解获取 token 中用户数据的相关文章

支付宝集成——如何在回调地址中使用自定义参数

支付宝集成——如何在回调地址中使用自定义参数 来源 http://www.solagirl.net/use-custom-para-in-alipay-return-url.html 2012 年 8 月 15 日 By Sola 支付宝集成时,有同步返回地址return_url和异步通知地址notify_url,这两个地址中的参数与签名验证有非常大的关系,在支付宝的说明中,强调return_url不可以有自定义参数,否则会导致sign和mysign不相等,但有时我们需要一些自定义参数来做判断,

Spring boot中普通工具类不能使用@Value注入yml文件中的自定义参数的问题

在写一个工具类的时候,因为要用到yml中的自定义参数,使用@Value发现值不能正常注入,都显示为null: yml文件中的自定义格式 调用工具类的时候不能new的方式 要使用@Autowired的方式注入进来, new会导致部分环境未加载,尽可能舍弃new的方式,交付spring管理 而工具类也是需要交给spring管理.需要在工具类上加上 @Component注解然后注意一下的是 在springframework下不能@Autowired静态变量 所以在变量上不能有 static 怎么扫描注

传递多个参数并获取Web API的数据

近段时间学习Web Api觉得非常有意思.默认的路由情况之下,获取数据时,它不必指定Action操作名. 还有另外感想,就是自从学习asp.net MVC之后,加上jQuery,让Insus.NET已经慢慢远离开ASP.NET,想起了那曾经得心应手的Web控件...... 前两篇<ASP.NET MVC的Web Api的实练>http://www.cnblogs.com/insus/p/4334316.html 没有带参数获取数据.而这篇<Html网页使用jQuery传递参数并获取Web

jQuery遍历table中的tr td并获取td中的值

jQuery遍历table中的tr td并获取td中的值 $(function(){ $("#tableId tr").find("td").each(function(){ <span style="white-space:pre"> </span> var year = $("#year").val(); var month = $("#month").val(); var da

XAF 框架中,自定义参数动作(Action),输入参数的控件可定义,用于选择组织及项目

XAF 框架中,如何生成一个自定义参数动作(Action),输入参数的控件可定义? 参考文档:https://documentation.devexpress.com/eXpressAppFramework/113183/Task-Based-Help/Actions/How-to-Customize-Action-Controls 示例 XAF 安装中带的 示例方案: Feature Center 默认安装在 :%PUBLIC%\Documents\DevExpress Demos 17.1\

Html网页使用jQuery传递参数并获取Web API的数据

昨天Insus.NET有开始学习Web API,<ASP.NET MVC的Web Api的实练>http://www.cnblogs.com/insus/p/4334316.html .其中演练中有提及到出现异常并解决,也有举例实现了在html静态网页使用jQuery来去读Web API的数据. 本篇想实现在html网页使用jQuery实现向Web API传递参数并获取数据. 在API创建一个方法public IEnumerable<Order> GetOrderByOrderNu

mybatis中接口的参数和mapper文件中的对映关系

有以下几种情况: 一个参数 不使用注解 1.参数为基本类型或包装类型.  参数注释为: #{任意字符} 2.参数为对象. 参数注释为: #{对象属性} 使用注解(@Param) 1.参数为基本类型或包装类型.  参数注释为: #{注解名称} | #{param1} 2.参数为对象. 参数注释为: #{注解名称.对象属性} | #{param1.对象属性} 多个参数 不使用注解 1.参数为基本类型或包装类型. 参数注释为: #{参数位置[0..n-1]} | #{param[1..n]} 2.参数

Android中如何解析网页,获取网页中的元素内容

问题: 由于android的WebView等相关类没有提供解析html网页内容的接口,我们想要获取网页的内容并解析出我们想要的元素内容,用android的固有API是没办法了. 这里我提供两种解析html思路:第一种,使用第三方解析html库:第二种,使用JAVA与JS回调,通过JS解析html. 之前研究了一下htmlparser这个开源库,但是发现和android提供的库有冲突,但其在纯java应用程序下是可行的. htmlparser下载地址:http://htmlparser.sourc

smarty中ifelse、foreach以及获取数组中键值名的一个实例

<{if empty($history)}> <tr> <td colspan="6">Not any records!</td> </tr> <{else}> <{foreach from=$history item=item}> <tr> <td><{$item.id}></td> <td> <div style="max-