• 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. 注解类 (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上预览此文章

  • 相关阅读:
    Grafana 监控系统是否重启
    Grafana 短信报警
    Python 协程检测Kubernetes服务端口
    python过滤 Kubernetes api数据
    django 实现文件下载功能
    python tar.gz格式压缩、解压
    kafka查看消费数据
    SublimeText设置在浏览器打开 快捷键
    php如何优雅地把数组传递给前端js脚本?
    jQuery因mouseover,mouseout冒泡产生的闪烁问题
  • 原文地址:https://www.cnblogs.com/roseAT/p/11828318.html
Copyright © 2020-2023  润新知