Servlet 过滤器(Filter)

一、过滤器是什么?

统一处理所有请求 / 响应,不用每个 Servlet 都写重复代码!

Servlet 过滤器 = 服务器端的 "门卫 / 拦截器"

  • 它在 请求到达 Servlet 之前 先拦截
  • 也可以在 响应返回客户端之前 再处理
  • 可以对请求、响应、会话做统一处理
  • 一个项目可以配多个过滤器,形成过滤链

二、过滤器能做什么?

  1. 统一编码设置(解决中文乱码)
  2. 登录校验(未登录不能访问)
  3. 权限控制
  4. 日志记录
  5. 请求 / 响应内容修改
  6. 压缩响应、跨域处理

三、过滤器核心接口

过滤器必须实现:javax.servlet.Filter接口

注意:必须重写 3 个方法:

  1. init():初始化(服务器启动时执行一次)
  2. doFilter() :核心过滤方法(每次请求都走这里)
  3. destroy():销毁(服务器关闭时执行)

四、过滤器执行流程(超级重要)

chain.doFilter(request, response)

  • 这行代码 = 放行,让请求继续往后走
  • 不写这行 = 拦截,请求到此为止

五、过滤器应用

1、统一编码过滤器(解决中文乱码)

java 复制代码
package org.hlx.javaweb3_0323;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * @author : HLX
 * @ClassName :CharacterFilter
 * @date : 2026/3/24 9:26
 * @Version :1.0
 * @Description: TODO
 * @modyified By :
 */
@WebFilter(urlPatterns = "/*", initParams = {@jakarta.servlet.annotation.WebInitParam(name = "encoding", value = "UTF-8")})
public class CharacterFilter implements Filter {
    // 获取初始化参数
    private String encoding;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 获取初始化参数
        String encoding = filterConfig.getInitParameter("encoding");
        if (encoding != null) {
            this.encoding = encoding;
        }
        System.out.println("1、字符编码过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //类型转换
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //设置编码格式
        request.setCharacterEncoding(encoding);
        response.setCharacterEncoding(encoding);
        response.setContentType("text/html;charset=" + encoding);
        //放行请求
        filterChain.doFilter(servletRequest, servletResponse);

        System.out.println("2、字符编码过滤器执行");

    }

    @Override
    public void destroy() {
        System.out.println("3、字符编码过滤器销毁");
    }
}

六、过滤器两种配置方式

1. 注解配置(最简单,推荐)

复制代码
@WebFilter(urlPatterns = "/*", initParams = {@WebInitParam(name = "encoding", value = "UTF-8")})

2. web.xml 配置(传统方式)

XML 复制代码
 <!-- 配置过滤器-->
    <filter>
        <filter-name>CharacterFilter</filter-name>
        <filter-class>org.hlx.javaweb3_0323.CharacterFilter</filter-class>
        <!-- 配置过滤器初始化参数-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 配置过滤器映射-->
    <filter-mapping>
        <filter-name>CharacterFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

七、多个过滤器执行顺序

  1. 注解 :按 类名字母顺序 执行
  2. web.xml :按 mapping 配置顺序 执行

2、登录校验过滤器(未登录不能访问)

java 复制代码
package org.hlx.javaweb3_0323;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

/**
 * @author : HLX
 * @ClassName :LoginFilter
 * @date : 2026/3/24 10:19
 * @Version :1.0
 * @Description: TODO
 * @modyified By :
 */
// 只拦截后台管理页面
@WebFilter("/admin/*")
public class LoginFilter implements jakarta.servlet.Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 类型转换
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 获取session对象
        HttpSession session = request.getSession();
        // 判断是否登录
        if (session.getAttribute("username") != null) {
            // 已登录,放行请求
            filterChain.doFilter(request, response);
        } else {
            // 未登录 → 拦截,跳转到登录页
            response.sendRedirect(request.getContextPath()+"/index.html");
        }
        System.out.println("2、登录过滤器拦截" + request.getRequestURI());
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("1、登录过滤器初始化");
    }

    @Override
    public void destroy() {
        System.out.println("3、登录过滤器销毁");
    }
}

总结

  1. Filter 是请求拦截器,统一处理请求 / 响应
  2. 必须实现 Filter 接口,重写 doFilter
  3. chain.doFilter() = 放行
  4. 最常用:统一编码、登录验证
相关推荐
Wang's Blog21 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
\光辉岁月/1 天前
5.java-数组
java·开发语言
谢亮_vipxieliang1 天前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
郑州光合科技余经理1 天前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_962071571 天前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
code2cat1 天前
Java进阶篇之AtomicReference:一次替换引用,读到一份完整状态
java·并发编程·不可变对象·atomicreference
专业程序开发源1 天前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
Wang's Blog1 天前
Java 项目实战: 外卖平台优化-前后端分离开发模式与工程拆分
java·开发语言
HEJOO91 天前
指针的算术运算详解
java·数据结构·算法
sunshine22 girl1 天前
Java学习六 Java常见API-2--String-3-字符串的截取替换和其他方法
java·开发语言·学习