Springboot实现过滤器

news2024/11/24 8:56:55

一、导言

在Spring Boot中,过滤器是一种用于对HTTP请求进行预处理和后处理的组件。相较于拦截器,过滤器属于Servlet规范的一部分,它能够在请求进入Web容器之前或返回给客户端之前进行操作。

要在Spring Boot中实现过滤器,可以按照以下步骤进行操作:

  1. 创建一个实现了javax.servlet.Filter接口的过滤器类,并实现其中的方法,例如init用于初始化过滤器doFilter用于实现过滤逻辑destroy用于销毁过滤器
  2. 在Spring Boot的配置类中,通过@Bean注解将过滤器类注册为一个Bean。
  3. 使用@ServletComponentScan注解来启用扫描Servlet组件(包括过滤器)的功能。
  4. 运行应用程序后,过滤器将会对符合条件的请求进行过滤处理。

下面是一个简单的示例代码:

@WebFilter(filterName = "MyFilter ",urlPatterns = "/*")//拦截全部
public class MyFilter implements Filter {
    /**
     *  servlet 容器在实例化过滤器后只调用一次 init 方法。
	 *	init 方法必须成功完成,然后才会要求筛选器执行任何筛选工作。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化逻辑
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 过滤逻辑
        chain.doFilter(request, response);
    }
    
    @Override
    public void destroy() {
        // 销毁逻辑
    }
}

在上述示例中,使用了@WebFilter注解将MyFilter类标记为过滤器,并通过urlPatterns拦截全部。

注意:为了使Spring Boot能够扫描到自定义的过滤器类,需要在启动类上使用@ServletComponentScan注解来开启扫描Servlet组件的功能。

@Slf4j
@ServletComponentScan//开启扫描Servlet组件的功能。
@SpringBootApplication
public class ReggieApplication {

    public static void main(String[] args) {
        SpringApplication.run(ReggieApplication.class, args);
        log.info("项目运行成功");
    }
}

通过实现过滤器,可以对HTTP请求进行一些通用操作,如身份验证请求日志记录字符编码设置等。过滤器在Servlet容器层面运行,比拦截器更早执行,因此可以对请求进行更底层的处理。

案例

实现未登录不能访问不需要处理的请求路径之外的路径操作:

案例需求:

以下路径可以跳过用户登录直接访问:

“/employee/login”,
“/employee/logout”,
"/backend/
",
“/front/",
"/common/
”,
“/user/sendMsg”,//移动端发送短信
“/user/login”,//移动端登录
//swagger
“/doc.html”,
"/webjars/",
“/swagger-resources”,
“/v2/api-docs”

若访问除上面的路径之外,需被拦截过滤看是否已经登录,若未登录,则直接跳到登录界面,若判断已经登录,则放行正常访问:

代码实现:

编写登录过滤器:LoginCheckFilter
这里包括了管理端和用户端两个登录过滤器

/**
 * 检查用户是否完成登录  
 * 若未完成不能访问除指定路径外的其他路径,直接跳到登录界面
 * 
 */
@Slf4j
@WebFilter(filterName = "LoginCheckFilter",urlPatterns = "/*")//拦截全部
public class LoginCheckFilter implements Filter {

    //路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1、获取本次请求的URI
        String requestURI = request.getRequestURI();// /backend/index.html

        log.info("拦截到请求:{}",requestURI);

        //定义不需要处理的请求路径
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**",
                "/common/**",
                "/user/sendMsg",//移动端发送短信
                "/user/login",//移动端登录
                //swagger
                "/doc.html",
                "/webjars/**",
                "/swagger-resources",
                "/v2/api-docs"

        };

        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);
        //3、如果不需要处理,则直接放行
        if (check == true) {
            log.info("本次请求不处理,直接放行:{}",requestURI);
            filterChain.doFilter(request,response);
            return;
        }
        //4、判断登录状态,如果已登录,则直接放行(登录状态session里面有登录对象的值)  管理端
        if (request.getSession().getAttribute("employee") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));

            long id = Thread.currentThread().getId();
            log.info("线程id为:{}",id);//处理公共字段无法用session得到用户id用   的线程测试


            //登录成功,将用户id存到一次线程当中,方便后续修改或增加数据时,得到更新或修改数据的操作用户的id
            Long employeeId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(employeeId);

            filterChain.doFilter(request,response);
            return;
        }


        //4、判断登录状态,如果已登录,则直接放行(登录状态session里面有登录对象的值)  移动端
        if (request.getSession().getAttribute("user") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));

            long id = Thread.currentThread().getId();
            log.info("线程id为:{}",id);//处理公共字段无法用session得到用户id用   的线程测试


            //登录成功,将用户id存到一次线程当中,方便后续修改或增加数据时,得到更新或修改数据的操作用户的id
            Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);

            filterChain.doFilter(request,response);
            return;
        }
            log.info("用户未登录");
            //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
            response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
            return;

    }

    /**
     * 路径匹配,检查本次请求是否需要放行参数 urls 是一个包含若干URL字符串的数组。
     * 参数 requestURI 是一个 HTTP 请求的 URI 字符串。
     * 该函数使用 Spring MVC 中的 PathMatcher 对象进行路径匹配,判断 requestURI 是否与 urls 中的某个 URL 匹配。
     * 如果匹配成功,则返回 true;否则返回 false。
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
        for (String url:urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match == true) {
                return true;
            }
        }
        return false;
    }

}

其中若用户未登录 ,执行下列的语句:给前端响应

  			log.info("用户未登录");
            //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
            response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
            return;

前端拦截器拿到响应的数据:做出判断,跳转页面:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

指针进阶(万字深层次指针解析)

❤️ 作者简介 :对纯音乐情有独钟的阿甘 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识,对纯音乐有独特的喜爱 📗 日后方向 : 偏向于CPP开发以及大数据方向,如果你也感兴趣的话欢迎关注博主,期待更新 指针进阶 …

Java正则表达式,不定期更新

Java正则表达式 1. 匹配数字(包含负数、小数)2. 匹配不是纯数字和纯字母且需要8位以上的密码3. 密码:字母、数字、符号(_-*.,!#符号可自定义)三选二4. 密码:必须包含大写、小写、数字、符号(_-*…

车道线检测|利用边缘检测的原理对车道线图片进行识别

前言 那么这里博主先安利一些干货满满的专栏了! 这两个都是博主在学习Linux操作系统过程中的记录,希望对大家的学习有帮助! 操作系统Operating Syshttps://blog.csdn.net/yu_cblog/category_12165502.html?spm1001.2014.3001.5482Linux S…

工程监测振弦采集仪的解决方案案例解释

振弦采集仪是一种用于测量结构物的振动状态和应力变化的高精度仪器,广泛应用于建筑、桥梁、隧道、地铁等工程领域。以下是一些常见的解决方案案例分析: 基础监测方案:对于大型建筑或桥梁工程,需要对基础进行实时监测。使用振弦采集…

System类 BigInterger BigDecimal

System类 常用方法和案例 exit: 退出当前程序 System.out.println("zhang"); // 0表示一个正常退出的状态 System.exit(0); System.out.println("cheng");System.arraycopy: 复制数组元素,比较适合底层的调用&#xf…

基于linux下的高并发服务器开发(第二章)- 2.2 进程状态转换

01 / 进程的状态 (1)三态模型 进程状态分为三个基本状态,即就绪态,运行态,阻塞态 (2)五态模型 在五态模型中,进程分为新建态,就绪态,运行态,阻…

mongodb练习---增删改查

环境: 1. 创建一个数据库 名字grade 2. 数据库中创建一个集合名字 class 3. 集合中插入若干数据 文档格式如下 {name:zhang,age;10,sex:m,hobby:[a,b,c]} hobby: draw sing dance basketball football pingpong compu…

Java8实战-总结2

Java8实战-总结2 基础知识方法和Lambda传递代码:一个例子从传递方法到Lambda 基础知识 方法和Lambda Scala和Groovy等语言的实践已经证明,让方法等概念作为一等值可以扩充程序员的工具库,从而让编程变得更容易。一旦程序员熟悉了这个强大的…

理解LLM中的ReAct

large language models (LLMs)大语言模型在语义理解和交互式决策方面有着不错的表现。ReAct在一次交互中循环使用推理和行动两个操作解决复杂问题,推理即利用模型自身语义理解能力,行动则利用模型以外的能力(如计算、搜索最新消息&#xff0c…

OpenCv之滤波器

目录 一、卷积 二、方盒滤波与均值滤波 三、高斯滤波 四、中值滤波 五、双边滤波 一、卷积 图像卷积就是卷积核在图像上按行华东遍历像素时不断的相乘求和的过程 相关知识点: 步长:就是卷积核在图像上移动的步幅.(为充分扫描图片,步长一般为1)padding:指在图片…

跨服务器跨库数据联合查询

今天群里有人问多个数据源, 可否显示在一个dbgrid, 我感觉是可以的 应该有两种办法 1,如果你两个服务器上都是用的mssqlserver, 那比较好办的, 如果不同数据库,如一个mssql,一个oracle。 则需要ssms方式创建。 通过SSMS查看,如果Microsoft OLE DB Provider for …

docekr-compose搭建redis集群(三主三从)

硬件:三台主机 172.50.2.40 172.50.2.41 172.50.2.42 需求:不想让它随机分配主从关系。想指定主从关系,如下: 主节点:172.50.2.40:6379,从节点172.50.2.41:6378 主节点:172.50.2.41:6379&…

C波段可调谐激光器控制软件系统

花了两周时间,利用下班时间,设计了一个ITLA可调谐激光器控制系统,从硬件到软件。下面这个图片整套硬件系统,软件硬件都自己设计,可以定制,做到单片机问题也不大。相当于一套光源了 这是软件使用的界面&…

PyTorch中的torch.nn.Linear函数解析

torch.nn是包含了构筑神经网络结构基本元素的包,在这个包中,可以找到任意的神经网络层。这些神经网络层都是nn.Module这个大类的子类。torch.nn.Linear就是神经网络中的线性层,可以实现形如yXweight^Tb的加和功能。 nn.Linear():…

Linux网络---网络预备

文章目录 计算机网络背景计算机网络协议网络传输基本流程 网络中的地址管理 一、计算机网络背景 独立模式: 计算机之间相互独立; 网络互联: 多台计算机连接在一起, 完成数据共享; 局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起 广域网WAN: 将远隔千里的计算机…

基于Javaweb实现ATM机系统开发实战(十二)用户转账功能实现

还是老规矩&#xff0c;先看前端传来怎样的参数&#xff1a; <% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8"%> <% taglib prefix"c" uri"http://java.sun.com/jsp/jstl/core"…

本地安装Linux虚拟机(超详细)

本文已收录于专栏 《运维》 目录 安装前准备虚拟机软件Linux镜像 安装过程中创建虚拟机安装linux系统 安装后测试 安装前准备 虚拟机软件 需要下载一个虚拟机软件&#xff0c;比如VirtualBox或VMware Workstation。这些软件可以创建和管理虚拟机。 这是VMware的官网&#xff1…

ceph集群(一)

ceph 一、存储基础分布式存储&#xff08;软件定义的存储 SDS&#xff09; 二、Ceph 简介Ceph 优势Ceph 架构Ceph 核心组件OSD 存储后端Ceph 数据的存储过程Ceph 集群部署 三、基于 ceph-deploy 部署 Ceph 集群实验Ceph 生产环境推荐&#xff1a;Ceph 环境规划部署 Ceph 集群 一…

Linux环境下,通过Docker搭建及配置RabbitMQ

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; Linux环境下&#xff0c;通过Docker搭建及配置RabbitMQ ⏱️ 创作时间…

SpringBoot--整合FreeMarker--使用/实例

原文网址&#xff1a;SpringBoot--整合FreeMarker--使用/实例_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SpringBoot如何使用FreeMarker。 配置文件 application.yml spring:#模板引擎 freemarkerfreemarker:# 模板后缀suffix: .ftl# 是否启用模板缓存cache: false# 模板编…