过滤器
Filter(过滤器)是Java Web中的一种拦截组件,运行在Servlet/JSP之前,用于对请求和响应进行统一预处理、后处理,而不修改业务逻辑本身。
主要用途
- 统一设置 编码格式
- 登录验证、权限控制
- 请求日志、敏感词过滤
- 对响应内容进行压缩、替换等
工作特点
- 请求先到Filter,再到Servlet/JSP
- 响应先从Servlet/JSP返回,再经过Filter
- 可配置多个,形成过滤链
- 基于 拦截—放行 机制,不侵入业务代码
flowchart LR
Client[客户端浏览器]:::info --> Request[HTTP请求]:::success
Request --> Filter1[过滤器1
Filter]:::warning
Filter1 --> Filter2[过滤器2
Filter]:::warning
Filter2 --> FilterN[过滤器N
Filter]:::warning
FilterN --> Servlet[Servlet/JSP
处理请求]:::primary
Servlet --> Response[响应数据]:::danger
Response --> FilterN
FilterN --> Filter2
Filter2 --> Filter1
Filter1 --> Client
过滤器生命周期
过滤器生命周期的各个阶段:
| HelloFilter |
|---|
| @WebFilter("/*")
public class HelloFilter extends HttpFilter implements Filter {
public HelloFilter() {
super();
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
public void destroy() {
}
}
|
源代码
| HelloFilter |
|---|
| import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
@WebFilter("/*")
public class HelloFilter extends HttpFilter implements Filter {
public HelloFilter() {
super();
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
public void destroy() {
}
}
|
过滤器定义
创建Filter分两步:
创建Filter类
| SimpleFilter1 |
|---|
| @WebFilter("/*")
public class SimpleFilter2 extends HttpFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.append("<p style='color: red;'>SimpleFilter2检查中...</p>");
chain.doFilter(request, response);
out.append("<p style='color: red;'>SimpleFilter2检查完成!</p>");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
|
源代码
| SimpleFilter1 |
|---|
| import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
public class SimpleFilter1 extends HttpFilter implements Filter {
private FilterConfig filterConfig;
public SimpleFilter1() {
super();
}
public void init(FilterConfig fConfig) throws ServletException {
this.filterConfig = fConfig;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.append("<p style='color: blue;'>SimpleFilter1检查中...</p>");
chain.doFilter(request, response);
out.append("<p style='color: red;'>SimpleFilter1检查中完成!</p>");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void destroy() {
}
}
|
URL映射
Filter有两种映射方式:注解、web.xml
过滤器链
过滤器链就是多个过滤器按配置顺序串联在一起,形成一条处理Web请求的链式调用流程。
- 客户端请求到来时,按顺序依次经过每个过滤器
- 每个过滤器做完处理后,决定是否放行(doFilter)
- 全部放行后,请求才到达 Servlet/JSP
- 响应返回时,按相反顺序再次经过过滤器链
- 整个过程像流水线一样,统一处理编码、登录、日志、权限等
flowchart LR
客户端:::success --> 过滤器1:::danger --> 过滤器2:::danger --> etc[...]:::danger --> 过滤器n:::danger --> Servlet/JSP:::primary
Servlet/JSP --> 过滤器n --> etc --> 过滤器2 --> 过滤器1 --> 客户端
示例
创建一个Servlet(DoSomethingServlet)接收客户端语法,创建一个客户端页面(hi_filter.html)发送Servlet请求,创建两个过滤器(SimpleFilter1,SimpleFilter2)监听全部URL请求
| DoSomethingServlet |
|---|
| @WebServlet("/DoSomthing")
public class DoSomethingServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<p style='color:green;'>我做了一些事!<p>");
}
}
|
源代码
| DoSomethingServlet |
|---|
| import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.annotation.WebServlet;
@WebServlet("/DoSomthing")
public class DoSomethingServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DoSomethingServlet() {
super();
}
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<p style='color:green;'>我做了一些事!<p>");
}
}
|
| demo/HelloFilter/src/main/webapp/hi_filter.html |
|---|
| <html>
<head>
<meta charset="utf-8">
<title> 新文档 </title>
</head>
<body>
<h1>欢迎使用第一个过滤器示例</h1>
<a href="/HelloFilter/DoSomthing">单击此处查看过滤器的效果</a>
</body>
</html>
|
| SimpleFilter1 |
|---|
| public class SimpleFilter1 extends HttpFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.append("<p style='color: blue;'>SimpleFilter1检查中...</p>");
chain.doFilter(request, response);
out.append("<p style='color: red;'>SimpleFilter1检查中完成!</p>");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
|
源代码
| SimpleFilter1 |
|---|
| import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
public class SimpleFilter1 extends HttpFilter implements Filter {
private FilterConfig filterConfig;
public SimpleFilter1() {
super();
}
public void init(FilterConfig fConfig) throws ServletException {
this.filterConfig = fConfig;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.append("<p style='color: blue;'>SimpleFilter1检查中...</p>");
chain.doFilter(request, response);
out.append("<p style='color: red;'>SimpleFilter1检查中完成!</p>");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void destroy() {
}
}
|
| SimpleFilter2 |
|---|
| @WebFilter("/*")
public class SimpleFilter2 extends HttpFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.append("<p style='color: red;'>SimpleFilter2检查中...</p>");
chain.doFilter(request, response);
out.append("<p style='color: red;'>SimpleFilter2检查完成!</p>");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
|
源代码
| SimpleFilter2 |
|---|
| import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
@WebFilter("/*")
public class SimpleFilter2 extends HttpFilter implements Filter {
private FilterConfig filterConfig;
public SimpleFilter2() {
super();
}
public void init(FilterConfig fConfig) throws ServletException {
this.filterConfig = fConfig;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.append("<p style='color: red;'>SimpleFilter2检查中...</p>");
chain.doFilter(request, response);
out.append("<p style='color: red;'>SimpleFilter2检查完成!</p>");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void destroy() {
}
}
|