Springboot登录验证的统一拦截处理的实现

 更新时间:2023年09月22日 09:47:01   作者:IDIOT___IDIOT  
如果不进行统一的拦截处理,每次用户请求你都要去进行用户的信息验证,所以本文主要介绍了Springboot登录验证的统一拦截处理的实现,感兴趣的可以了解一下,感兴趣的可以了解一下

在进行Springboot项目开发的时候如何把每次请求都要验证的用户进行提取拦截统一处理

背景

如果不进行统一的拦截处理,其实这是一个非常痛苦的一件事情,因为每次用户请求你都要去进行用户的信息(用户信息存储在session中)的验证,代码重复,所以在本篇提供一个解决方案:

定义一个拦截器,把请求都进行统一的处理,如果Session中存在用户的信息那么就放行;如果不存在,那么就直接出现异常报错未登录。在这样的一个方案中其实还存在着一个问题,在业务逻辑中我要去获取用户的信息,那不又是很麻烦了?这里可以通过ThreadLocal解决。

为什么用ThreadLocal:当用户发起请求时,会访问我们像tomcat注册的端口,任何程序想要运行,都需要有一个线程对当前端口号进行监听,tomcat也不例外,当监听线程知道用户想要和tomcat连接连接时,那会由监听线程创建socket连接,socket都是成对出现的,用户通过socket像互相传递数据,当tomcat端的socket接受到数据后,此时监听线程会从tomcat的线程池中取出一个线程执行用户请求,在我们的服务部署到tomcat后,线程会找到用户想要访问的工程,然后用这个线程转发到工程中的controller,service,dao中,并且访问对应的DB,在用户执行完请求后,再统一返回,再找到tomcat端的socket,再将数据写回到用户端的socket,完成请求和响应通过以上讲解,我们可以得知 每个用户其实对应都是去找tomcat线程池中的一个线程来完成工作的, 使用完成后再进行回收,既然每个请求都是独立的,所以在每个用户去访问我们的工程时,我们可以使用threadlocal来做到线程隔离,每个线程操作自己的一份数据

定义一个ThreadLocal线程工具类

便于对线程内部的值进行处理。

public class UserHolder {
    public static final ThreadLocal<User> userThreadLocal = new ThreadLocal<>();
    public static void setValue(User user){
        userThreadLocal.set(user);
    }
    public static User getValue(){
        return userThreadLocal.get();
    }
    public static  void clear(){
        userThreadLocal.remove();
    }
}

定义拦截器

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 获取 session
        HttpSession session = request.getSession();
        // 检查用户是否已登录
        if (session.getAttribute("user") == null) {
            // 用户未登录,进行相关处理
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        // 从 session 中获取用户数据
        User user = (User) session.getAttribute("user");
        // 将用户数据存储到 ThreadLocal 中,以便在整个请求周期内访问
        UserHolder.setValue(user);
        // 进行其他逻辑验证,根据需求自行添加
        return true; // 允许请求继续执行
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 在请求处理之后执行,可以对 ModelAndView 进行修改
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // 在请求完成之后执行,用于资源清理等操作
        // 清理 ThreadLocal 中的用户数据,防止内存泄漏
        UserHolder.clear();
    }
}

让拦截器生效

通过配置让拦截器生效

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器
        // excludePath 就是排除在外被拦截的路径
        registry.addInterceptor(new LoginInterceptor())
            	.addPathPatterns("/**")  
                .excludePathPatterns(
                        "/user/login"
                );
    }
}

然后就可以啦

测试

测试Controller

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @PostMapping("/login")
    public BaseResponse<User> login(HttpSession session){
        System.out.println("Hello");
        Random random = new Random(new Date().getTime()) ;
        User user = new User(random.nextLong(), "123","123454","123");
        session.setAttribute("user",user);
        return ResultUtils.success(user);
    }
    @GetMapping("/get")
    public BaseResponse<User> get(){
        return ResultUtils.success(UserHolder.getValue());
    }
}

测试结果

开始没有登录

进行登录

再次获取get请求就可以了

这里我出现一个问题我一直调试了很久,md,就是在配置拦截器的时候添加路径首先把所有路径进行拦截,然后放行/user/login就好,我的这个项目在配置文件中给所有的路径首先加了一个/api这样的前缀,然后我在拦截路径的时候都加了api,这个其实是不用加的,直接上路径就好了,spring自动会加。

到此这篇关于Springboot登录验证的统一拦截处理的实现的文章就介绍到这了,更多相关Springboot登录验证统一拦截处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中Spring的单例模式使用

    Java中Spring的单例模式使用

    这篇文章主要介绍了Java中Spring的单例模式使用,spring中的单例也不影响应用并发访问。大多数时候客户端都在访问我们应用中的业务对象,为减少并发控制,不应该在业务对象中设置那些容易造成出错的成员变量,下面一起进入文章了解更多详细内容吧
    2022-01-01
  • Java编程实现多线程TCP服务器完整实例

    Java编程实现多线程TCP服务器完整实例

    这篇文章主要介绍了Java编程实现多线程TCP服务器完整实例,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • SpringBoot单元测试之数据隔离详解

    SpringBoot单元测试之数据隔离详解

    我们在写单元测试时,有一个比较重要的要求是可以重复运行, 那么这样就会有一个比较麻烦的问题:数据污染,所以本文为大家整理了两个数据隔离的方式,希望对大家有所帮助
    2023-08-08
  • mybatis plus常用注解的具体使用

    mybatis plus常用注解的具体使用

    本文主要介绍了mybatis plus常用注解的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • SpringBoot拦截器原理解析及使用方法

    SpringBoot拦截器原理解析及使用方法

    这篇文章主要介绍了SpringBoot拦截器原理解析及使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 使用@Cacheable缓存解决双冒号::的问题

    使用@Cacheable缓存解决双冒号::的问题

    这篇文章主要介绍了使用@Cacheable缓存解决双冒号::的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • springboot跨域问题解决方案

    springboot跨域问题解决方案

    这篇文章主要介绍了springboot跨域问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • spring boot与spring mvc的区别及功能介绍

    spring boot与spring mvc的区别及功能介绍

    这篇文章主要介绍了spring boot与spring mvc的区别是什么以及spring boot和spring mvc功能介绍,感兴趣的朋友一起看看吧
    2018-02-02
  • Spring使用注解进行引用类型的自动装配逐步分析

    Spring使用注解进行引用类型的自动装配逐步分析

    自动装配是springboot的核心,一般提到自动装配就会和springboot联系在一起。实际上Spring Framework早就实现了这个功能。Spring Boot只是在其基础上,通过SPI的方式,做了进一步优化
    2023-03-03
  • SpringBoot2.0整合Redis自定义注入bean组件配置的实战教程

    SpringBoot2.0整合Redis自定义注入bean组件配置的实战教程

    这篇文章主要介绍了SpringBoot2.0整合Redis自定义注入bean组件配置,我们将基于SpringBoot2.0整合搭建的微服务项目为奠基,开启中间件Redis的实战之路,需要的朋友可以参考下
    2023-06-06

最新评论