Java Web-Filter

Filter

在 Java Web 开发中,Filter(过滤器)是 Servlet 规范中的一个重要组件,它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter:

一、概念和作用

  • 概念:Filter 是一种特殊的 Servlet 组件,它可以在请求到达目标资源(如 Servlet、JSP 等)之前或响应返回客户端之前对请求和响应进行拦截和处理。
  • 作用
    • 权限验证:检查用户是否具有访问某个资源的权限,例如在用户未登录时阻止其访问需要登录才能访问的页面。
    • 字符编码处理:统一设置请求和响应的字符编码,避免出现乱码问题。
    • 日志记录:记录每个请求的详细信息,如请求的 URL、参数、请求时间等,方便后续的系统监控和问题排查。
    • 数据过滤和验证:对请求参数进行过滤和验证,防止恶意输入或不符合要求的数据进入系统。

二、工作原理

当客户端发送请求到服务器时,请求首先会经过一系列的 Filter。每个 Filter 可以对请求进行检查和修改,然后将请求传递给下一个 Filter 或目标资源。当目标资源处理完请求后,响应会按照相反的顺序再次经过这些 Filter,每个 Filter 可以对响应进行后处理,最后将响应返回给客户端。

实现步骤

1. 创建 Filter 类

Filter 类需要实现 javax.servlet.Filter 接口,并重写其中的三个方法:init()doFilter() 和 destroy()

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化方法,在 Filter 实例创建后调用,可用于初始化资源
        System.out.println("MyFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 过滤方法,对请求和响应进行处理
        System.out.println("MyFilter 开始处理请求");
        // 设置请求和响应的字符编码
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        // 将请求和响应传递给下一个 Filter 或目标资源
        chain.doFilter(request, response);
        System.out.println("MyFilter 处理响应结束");
    }

    @Override
    public void destroy() {
        // 销毁方法,在 Filter 实例销毁前调用,可用于释放资源
        System.out.println("MyFilter 销毁");
    }
}
2. 配置 Filter

有两种常见的配置方式:使用 web.xml 配置文件或使用注解。

使用 web.xml 配置

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <!-- 过滤所有请求 -->
    <url-pattern>/*</url-pattern>
</filter-mapping>

用注解配置

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    // 省略方法实现
}

三、Filter 链

在 Java Web 开发中,过滤器链(Filter Chain)是一个重要的概念,它允许多个过滤器(Filter)按照特定顺序对请求和响应进行处理。下面将从过滤器链的概念、工作原理、配置方式、执行顺序以及应用场景等方面进行详细解释。

概念

过滤器链是由多个过滤器组成的一个有序列表。当客户端向服务器发送请求时,请求会依次经过过滤器链中的每个过滤器,每个过滤器可以对请求进行预处理,如验证用户身份、设置字符编码等。当请求到达目标资源(如 Servlet、JSP 等)并处理完成后,响应会按照相反的顺序再次经过过滤器链,每个过滤器可以对响应进行后处理,如压缩响应数据、添加响应头信息等。

工作原理

  1. 请求阶段:客户端发送请求到服务器,服务器接收到请求后,会根据配置的过滤器链,依次将请求传递给链中的每个过滤器。每个过滤器在接收到请求后,可以对请求进行修改或增强,然后将请求传递给下一个过滤器。如果某个过滤器决定不将请求继续传递给下一个过滤器,它可以直接返回响应给客户端,从而终止请求的处理流程。
  2. 响应阶段:当请求到达目标资源并处理完成后,服务器会生成响应。响应会按照与请求阶段相反的顺序经过过滤器链,每个过滤器可以对响应进行修改或增强,最后将响应返回给客户端。

配置方式

可以通过 web.xml 配置文件或注解的方式来配置过滤器链。

使用 web.xml 配置
<filter>
    <filter-name>Filter1</filter-name>
    <filter-class>com.example.Filter1</filter-class>
</filter>
<filter>
    <filter-name>Filter2</filter-name>
    <filter-class>com.example.Filter2</filter-class>
</filter>
<filter-mapping>
    <filter-name>Filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Filter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在上述配置中,Filter1 和 Filter2 会组成一个过滤器链,请求会先经过 Filter1,再经过 Filter2

使用注解配置
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*", filterName = "Filter1")
public class Filter1 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 预处理逻辑
        System.out.println("Filter1: 请求预处理");
        chain.doFilter(request, response);
        // 后处理逻辑
        System.out.println("Filter1: 响应后处理");
    }
}

@WebFilter(urlPatterns = "/*", filterName = "Filter2")
public class Filter2 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 预处理逻辑
        System.out.println("Filter2: 请求预处理");
        chain.doFilter(request, response);
        // 后处理逻辑
        System.out.println("Filter2: 响应后处理");
    }
}

在上述代码中,Filter1 和 Filter2 都会对所有请求进行拦截,具体的执行顺序可能因 Servlet 容器而异。

执行顺序

  • web.xml 配置:在 web.xml 中,<filter-mapping> 标签的配置顺序决定了过滤器的执行顺序。先配置的过滤器会先执行,后配置的过滤器后执行。
  • 注解配置:使用注解配置时,不同的 Servlet 容器可能有不同的处理方式。有些容器会按照类名的字典序来决定过滤器的执行顺序,而有些容器可能没有明确的顺序。为了确保过滤器按照预期的顺序执行,建议使用 web.xml 进行配置。

应用场景

  • 身份验证和授权:可以使用多个过滤器来实现不同级别的身份验证和授权。例如,一个过滤器用于验证用户是否已登录,另一个过滤器用于验证用户是否具有访问特定资源的权限。
  • 字符编码处理:可以在过滤器链中配置一个过滤器,用于统一设置请求和响应的字符编码,避免出现乱码问题。
  • 日志记录:可以使用过滤器链来记录每个请求的详细信息,如请求的 URL、参数、请求时间等,方便后续的系统监控和问题排查。
  • 数据过滤和验证:可以在过滤器链中配置多个过滤器,对请求参数进行过滤和验证,防止恶意输入或不符合要求的数据进入系统。

示例代码执行结果分析

假设有上述的 Filter1 和 Filter2 两个过滤器,当客户端发送一个请求时,控制台可能会输出以下信息:

Filter1: 请求预处理
Filter2: 请求预处理
(目标资源处理请求)
Filter2: 响应后处理
Filter1: 响应后处理

从输出结果可以看出,请求阶段过滤器按照 Filter1 -> Filter2 的顺序执行,响应阶段过滤器按照 Filter2 -> Filter1 的顺序执行。

通过使用过滤器链,可以将不同的功能逻辑分离到不同的过滤器中,提高代码的可维护性和可扩展性。

四、应用场景举例

登录验证 Filter
package com.itheima.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter("/*")
public class LoginFilter implements Filter {
    // 未登录即可放行的资源列表,常量
    private static final String[] PUBLIC_URLS = {
           "/adminServlet","index.html", "admin.jsp", "register.jsp", "/registerServlet", "login.jsp", "/loginServlet"
    };

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 设置请求和响应的字符编码,避免中文乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        HttpServletRequest req = (HttpServletRequest) request;
        // 获取请求的 URI 部分
        String uri = req.getRequestURI();

        // 检查是否为未登录即可放行的资源
        for (String u : PUBLIC_URLS) {
            if (uri.endsWith(u)) {
                // 可以放行
                chain.doFilter(request, response);
                return;
            }
        }

        // 到这步说明访问的资源不可以直接放行,必须登录
        HttpSession session = req.getSession();
        Object user = session.getAttribute("user");
        Object admin = session.getAttribute("admin");

        // 判断 user 或 admin 是否不为 null
        if (user != null || admin != null) {
            // 用户或管理员已登录,放行请求
            chain.doFilter(request, response);
        } else {
            // 没登陆过,跳转到登录页面
            req.setAttribute("login_errmsg", "请登录");
            req.getRequestDispatcher("login.jsp").forward(request, response);
        }
    }

    @Override
    public void destroy() {
    }
}

这个 Filter 会检查用户是否已登录,如果未登录则重定向到登录页面。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

水果识别系统 | BP神经网络水果识别系统,含GUI界面(Matlab)

使用说明 代码下载&#xff1a;BP神经网络水果识别系统&#xff0c;含GUI界面&#xff08;Matlab&#xff09; BP神经网络水果识别系统 一、引言 1.1、研究背景及意义 在当今科技迅速发展的背景下&#xff0c;人工智能技术尤其是在图像识别领域的应用日益广泛。水果识别作为…

Spark核心之01:架构部署、sparkshell、程序模板

spark内存计算框架 一、主题 spark核心概念spark集群架构spark集群安装部署spark-shell的使用通过IDEA开发spark程序 二、要点 1. spark是什么 Apache Spark™ is a unified analytics engine for large-scale data processing. spark是针对于大规模数据处理的统一分析引擎…

Sparsely-Gated Mixture-of-Experts Layer (MoE)论文解读与Pytorch代码实现

MoE解析 阅读论文&#xff1a;https://arxiv.org/pdf/1701.06538 OUTRAGEOUSLY LARGE NEURAL NETWORKS:THE SPARSELY-GATED MIXTURE-OF-EXPERTS LAYER 本文介绍了一种名为Sparsely-Gated Mixture-of-Experts Layer (MoE) 的神经网络组件&#xff0c;旨在通过条件计算&#xf…

线性模型 - 支持向量机

支持向量机&#xff08;SVM&#xff09;是一种用于分类&#xff08;和回归&#xff09;的监督学习算法&#xff0c;其主要目标是找到一个最佳决策超平面&#xff0c;将数据点分为不同的类别&#xff0c;并且使得分类边界与最近的数据点之间的间隔&#xff08;margin&#xff09…

利用STM32TIM自制延迟函数实验

一、实验目的 掌握STM32定时器&#xff08;TIM&#xff09;的工作原理及配置方法学习使用HAL库实现微秒级/毫秒级延时函数理解定时器中断服务程序的编写规范 二、实验原理 ​定时器基础&#xff1a; STM32定时器包含向上计数器、向下计数器、中心对齐模式通过预分频器&#x…

mac安装环境

minconda https://docs.anaconda.net.cn/miniconda/install/ 注意在下载下来应该有100多兆&#xff0c;太大了应该是完整版&#xff0c;我们不需要 jdk 镜像网站下载设置环境变量&#xff1a; 终端&#xff1a;sudo vim ~/.zshrc # JDK Config JAVA_HOME/Library/Java/Java…

视觉图像坐标转换

1. 透镜成像 相机的镜头系统将三维场景中的光线聚焦到一个平面&#xff08;即传感器&#xff09;。这个过程可以用小孔成像模型来近似描述&#xff0c;尽管实际相机使用复杂的透镜系统来减少畸变和提高成像质量。 小孔成像模型&#xff1a; 假设有一个理想的小孔&#xff0c;…

计算机毕业设计SpringBoot+Vue.js景区民宿预约系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【LeetCode: SQL专题 : SQL132 每个题目和每份试卷被作答的人数和次数 + 合并查询】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

动态内容加载的解决方案:Selenium与Playwright对比故障排查实录

方案进程 2024-09-01 09:00 | 接到亚航航班数据采集需求 2024-09-01 11:30 | 首次尝试使用Selenium遭遇Cloudflare验证 2024-09-01 14:00 | 切换Playwright方案仍触发反爬机制 2024-09-01 16:30 | 引入爬虫代理IPUA轮换策略 2024-09-02 10:00 | 双方案完整实现并通过压力测试故…

不同规模企业如何精准选择AI工具: DeepSeek、Grok 和 ChatGPT 三款主流 AI 工具深度剖析与对比

本文深入探讨了最近国内外主流的 DeepSeek、Grok 和 ChatGPT 三款主流 AI 工具的技术细节、性能表现、应用场景及局限性&#xff0c;并从技术能力、功能需求、成本预算、数据安全和合规以及服务与支持五个关键维度&#xff0c;详细分析了不同规模企业在选择 AI 工具时的考量因素…

利用 Python 爬虫进行跨境电商数据采集

1 引言2 代理IP的优势3 获取代理IP账号4 爬取实战案例---&#xff08;某电商网站爬取&#xff09;4.1 网站分析4.2 编写代码4.3 优化代码 5 总结 1 引言 在数字化时代&#xff0c;数据作为核心资源蕴含重要价值&#xff0c;网络爬虫成为企业洞察市场趋势、学术研究探索未知领域…

【数据挖掘】Matplotlib

Matplotlib 是 Python 最常用的 数据可视化 库之一&#xff0c;在数据挖掘过程中&#xff0c;主要用于 数据探索 (EDA)、趋势分析、模式识别 和 结果展示。 &#x1f4cc; 1. Matplotlib 基础 1.1 安装 & 导入 # 如果未安装 Matplotlib&#xff0c;请先安装 # pip instal…

使用Java构建高效的Web服务架构

使用Java构建高效的Web服务架构 随着互联网技术的飞速发展&#xff0c;Web服务在现代应用中扮演着至关重要的角色。尤其是在企业级应用中&#xff0c;如何构建一个高效、可扩展且易维护的Web服务架构&#xff0c;成为了开发者和架构师面临的一项重要挑战。Java作为一种成熟、稳…

数据库MySQL,在终端输入后,提示不是内部命令等

【解决问题】mysql提示不是内部或外部命令&#xff0c;也不是可运行的程序 一般这种问题是因为没有在系统变量里面添加MySQL的可执行路径 以下是添加可执行路径的方法&#xff1a; 第一步&#xff1a;winR输入services.msc 然后找到MySQL&#xff0c;右击属性并复制MySQL的可执…

LabVIEW正弦信号处理:FFT与最小二乘拟合的参数提取

问题一&#xff1a;LabVIEW能否对采集的正弦力信号进行快速傅里叶变换&#xff08;FFT&#xff09;&#xff0c;并得到幅值和相位结果&#xff1f; 答案&#xff1a; 可以。LabVIEW通过内置信号处理工具包提供完整的FFT分析功能&#xff0c;具体实现如下&#xff1a; FFT分析流…

Hive-05之查询 分组、排序、case when、 什么情况下Hive可以避免进行MapReduce

一、目标 掌握hive中select查询语句中的基本语法掌握hive中select查询语句的分组掌握hive中select查询语句中的join掌握hive中select查询语句中的排序 二、要点 1. 基本查询 注意 SQL 语言大小写不敏感SQL 可以写在一行或者多行关键字不能被缩写也不能分行各子句一般要分行…

React:B站评论demo,实现列表渲染、删除按钮显示和功能实现、导航栏渲染切换及高亮显示、评论区的排序

功能要求&#xff1a; 1、渲染评论列表 2、删除评论功能&#xff1a;只显示自己评论的删除按钮&#xff1b;点击删除按钮&#xff0c;删除当前评论&#xff0c;列表中不再显示。 3、渲染导航Tab&#xff08;最新 | 最热&#xff09;和其 高亮实现 4、评论排序功能实现&…

ST表解决RMQ问题

引入 给定你一个长度为n的数组a&#xff0c;再给你q次询问&#xff0c;每次询问给定你一个区间[L,R]&#xff0c;让你求a数组中L~R中的最大值/最小值 我们利用常规算法求时很显然会超时&#xff0c;以此我们需要一个数据结构——ST表来解决 ST表 ST表是一个类似于线段树的东…

[数据结构] - - - 链表

一、定义 链表&#xff1a;是一种常见的线性数据结构&#xff0c;它通过一组节点&#xff08;Node&#xff09;来存储数据&#xff0c;每个节点包含两部分&#xff1a;数据域和指针域。 1.1 链表的基本概念 节点&#xff08;Node&#xff09;&#xff1a;链表的最小单元&#…