SpringBoot通过参数注解自动获取当前用户信息的方法

 更新时间:2024年03月12日 09:46:28   作者:写程序的小熊猫  
这篇文章主要介绍了SpringBoot通过参数注解自动获取当前用户信息的方法,文中使用HandlerMethodArgumentResolver 类来实现这个功能,并通过代码示例讲解的非常详细,需要的朋友可以参考下

需求:通过注解实现自动获取当前用户信息

思路:使用HandlerMethodArgumentResolver 类来实现这个功能;

这个接口有两个方法,supportsParameter和resolveArgument。

  1. 方法supportsParameter返回值是boolean类型,它的作用是判断Controller层中的参数,是否满足条件,满足条件则执行resolveArgument方法,不满足则跳过。
  2. resolveArgument方法,它只有在supportsParameter方法返回true的情况下才会被调用。用于处理一些业务,将返回值赋值给Controller层中的这个参数。

执行流程

1.请求 ->
2.拦截器(获取当前用户并放在UserContext中)->
3.Controller->参数解析器(检测到参数中有设置的注解和参数,则给参数赋值) ->
4.service中进行使用当前用户信息

Controller

package com.haier.strategy.resolution.controller;

@Slf4j
@RestController
@RequestMapping("/api/v1/test")
@Tag(name = "测试")
public class TestController {

    @Autowired
    private TestService testService;



    /**
     * 测试
     *
     * @param name
     * @return
     */
    @Operation(summary = "测试,根据姓名获取学生信息")
    @GetMapping("/getByName")
    public StudentVo getByName(@RequestParam("name") String name, @Parameter(hidden = true) @LoginUser UserBo userBo) {
        return testService.getByName(name, userBo);
    }

controller通过在参数中注明 @LoginUser UserBo userBo就可以实现在service中获取当前用户信息

注解

/**
 * 标记需要解析为用户信息的参数
 *
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginUser {
    boolean required() default true;

}

用户实体类

/**
 * @Description: 用户实体类
 * @Version: V1.0
 */
@Schema(description = "用户实体类")
@Data
public class UserBo {

    @Schema(description = "用户姓名")
    private String userName;
    @Schema(description = "用户工号")
    private String jobNo;

}

userContext


/**
 * 用户上下文UTIL
 *
 */
public class UserContext {

    /**
     * User holder
     * 考虑 TransmittableThreadLocal
     */
    private static final TransmittableThreadLocal<UserBo> CURRENT_USER_HOLDER = new TransmittableThreadLocal<>();
    private static final TransmittableThreadLocal<String> CURRENT_AUTHORIZATION = new TransmittableThreadLocal<>();

    /**
     * 保存 session
     *
     */
    public static void saveUser(UserBo user) {
        CURRENT_USER_HOLDER.set(user);
    }

    /**
     * 保存authorization
     */
    public static void saveAuthorization(String authorization) {
        CURRENT_AUTHORIZATION.set(authorization);
    }

    /**
     * 获取authorization
     */
    public static String getAuthorization() {
        return CURRENT_AUTHORIZATION.get();
    }

    /**
     * 删除authorization
     */
    public static void removeAuthorization() {
        CURRENT_AUTHORIZATION.remove();
    }

    /**
     * 当前用户
     *
     */
    public static UserBo currentUser() {
        return CURRENT_USER_HOLDER.get();
    }

    /**
     * remove session
     *
     */
    public static void removeUser() {
        CURRENT_USER_HOLDER.remove();
    }
}

拦截器

@Slf4j
@Component
public class UserLoginInterceptor implements HandlerInterceptor {

    @Autowired
    @Lazy
    private StrategyCommonClient strategyCommonClient;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader(CommonConst.ACCESS_TOKEN);
        String authorization = request.getHeader(CommonConst.AUTHORIZATION);
        UserContext.saveAuthorization(authorization);
        String userCode = request.getHeader(CommonConst.USER_CODE);
        ResultBody<UserBo> userRes;
        try {
            //通过认证服务获取当前用户信息
            userRes = commonClient.getUserInfo(userCode, token);
        } catch (Exception e) {
            throw new Exception("get_user_info_fail");
        }
        if (userRes.getCode() != 200 || userRes.getData() == null) {
            throw new Exception("get_user_info_fail");
        }
        UserContext.saveUser(userRes.getData());
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //do nothing
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserContext.removeUser();
        UserContext.removeAuthorization();
    }
}


参数解析器

@Slf4j
@Component
public class LoginUserResolver implements HandlerMethodArgumentResolver {

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

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        return UserContext.currentUser();
    }
}

到此这篇关于SpringBoot通过参数注解自动获取当前用户信息功能的文章就介绍到这了,更多相关SpringBoot参数注解获取信息内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 三分钟带你了解SpringBoot真正的启动引导类

    三分钟带你了解SpringBoot真正的启动引导类

    这篇文章主要介绍了三分钟带你了解SpringBoot真正的启动引导类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Mybatis plugin的使用及原理示例解析

    Mybatis plugin的使用及原理示例解析

    这篇文章主要为大家介绍了 Mybatis plugin的使用及原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 详解Java设计模式编程中的Flyweight享元模式的开发结构

    详解Java设计模式编程中的Flyweight享元模式的开发结构

    这篇文章主要介绍了Java设计模式编程中的Flyweight享元模式的开发结构,享元模式能够最大限度地重用现有的同类对象,需要的朋友可以参考下
    2016-04-04
  • Springboot实现邮箱验证代码实例

    Springboot实现邮箱验证代码实例

    这篇文章主要介绍了Springboot实现邮箱验证代码实例,在一些业务需求中我们经常需要使用邮箱进行验证码的收取,本文通过简单的代码实例来说明,需要的朋友可以参考下
    2024-01-01
  • java实现求只出现一次的数字

    java实现求只出现一次的数字

    本文主要介绍了java实现求只出现一次的数字,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 深入学习Java同步机制中的底层实现

    深入学习Java同步机制中的底层实现

    在多线程编程中我们会遇到很多需要使用线程同步机制去解决的并发问题,这些同步机制是如何实现的呢?下面和小编来一起学习吧
    2019-05-05
  • 浅析Java如何高效将PDF转换为高质量TIFF图片

    浅析Java如何高效将PDF转换为高质量TIFF图片

    在文档处理和归档系统中,将PDF文件转换为TIFF格式是一项非常常见的需求,本文将介绍如何使用Java通过Spire.PDF for Java库,快速实现PDF到TIFF的转换,希望对大家有所帮助
    2026-04-04
  • Spring Retry重试框架的使用讲解

    Spring Retry重试框架的使用讲解

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次。用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有,感兴趣的可以了解一下
    2023-01-01
  • Java 深入浅出掌握Map集合之双列集合

    Java 深入浅出掌握Map集合之双列集合

    双列集合是每个元素都有键与值两部分组成的集合,记录的是键值对对应关系,即通过键可以找到值,键必须是唯一,值可以重复,接下来跟着小编具体了解吧
    2021-11-11
  • java自定义类加载器代码示例

    java自定义类加载器代码示例

    这篇文章主要介绍了java自定义类加载器代码示例,具有一定借鉴价值,需要的朋友可以了解下。
    2017-12-12

最新评论