想象一下,你正在搭建一个网站,用户需要登录才能访问某些页面。你肯定不希望未经授权的用户能够随意浏览或修改重要信息,这时,你就需要一个“安全门”来保护你的网站,而 Java Filter 就是扮演这个角色的最佳人选!
Filter 就像一个尽职尽责的“保安”,专门负责检查进出网站的人员和货物。它拦截每一个来自客户端(例如浏览器)的请求,并在请求到达最终目的地(例如 Servlet 或 JSP 页面)之前进行一系列的检查和处理。同样地,当服务器准备将响应发送回客户端时,Filter 也会再次进行拦截,对响应内容进行修改或添加额外的信息。
Filter 的生命周期由 Servlet 容器(例如 Tomcat)全权负责,就像保安在岗时间一样,有着严格的管理:
为了让 Filter 能够完成各种任务,Java Servlet API 提供了一套强大的武器库,让 Filter 能够应对各种挑战:
打造一个专属 Filter 非常简单,只需三步即可完成:
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作,例如获取配置参数
String param = filterConfig.getInitParameter("paramName");
System.out.println("Filter 初始化参数:" + param);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 预处理操作,例如打印请求路径
HttpServletRequest req = (HttpServletRequest) request;
System.out.println("请求路径:" + req.getRequestURI());
// 调用 chain.doFilter() 方法,将请求传递给下一个 Filter 或目标资源
chain.doFilter(request, response);
// 后处理操作,例如打印响应内容
System.out.println("响应内容:" + response.getContentType());
}
@Override
public void destroy() {
// 销毁操作,例如释放资源
System.out.println("Filter 销毁");
}
}
配置 Filter 有两种方式:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
<init-param>
<param-name>paramName</param-name>
<param-value>paramValue</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/myServlet</url-pattern>
</filter-mapping>
@WebFilter(filterName = "myFilter", urlPatterns = "/myServlet", initParams = {
@WebInitParam(name = "paramName", value = "paramValue")
})
public class MyFilter implements Filter {
// ...
}
执行流程我们搞清楚之后,接下来再来介绍一下过滤器的拦截路径,Filter可以根据需求,配置不同的拦截资源路径:
拦截路径 | urlPatterns值 | 含义 |
---|---|---|
拦截具体路径 | /login | 只有访问 /login 路径时,才会被拦截 |
目录拦截 | /stus/* | 访问/stus下的所有资源,都会被拦截 |
拦截所有 | /* | 访问所有资源,都会被拦截 |
在 Spring Boot 项目中,使用 Filter 更加方便,你只需要使用 @Component 注解将 Filter 注册为 Spring Bean,并使用 @WebFilter 注解配置其拦截路径即可。
@Component
@WebFilter(urlPatterns = "/*", filterName = "loginFilter") //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )
public class LoginFilter implements Filter {
@Override //初始化方法, 只调用一次
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init 初始化方法执行了");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("DemoFilter 放行前逻辑.....");
//放行请求
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("DemoFilter 放行后逻辑.....");
}
@Override //销毁方法, 只调用一次
public void destroy() {
System.out.println("destroy 销毁方法执行了");
}
}
当多个 Filter 同时拦截同一个请求时,它们会组成一个 FilterChain,就像一条链条一样,依次对请求进行处理。FilterChain 维护了 Filter 的执行顺序,并通过 doFilter() 方法将请求传递给下一个 Filter。
请求
----->
[Filter 1] --> [Filter 2] --> [目标资源]
<-----
响应
请求:1 -> 2
响应:2 -> 1
完整:1 -> 2 -> 2 -> 1
假设我们正在开发一个电商网站,用户需要登录才能进行下单操作。为了保证网站安全,我们需要使用 Filter 对所有请求进行拦截,检查用户是否登录,如果未登录,则跳转到登录页面。
@Component
@WebFilter(urlPatterns = {"/order/*"}, filterName = "authFilter")
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 获取用户信息
User user = (User) req.getSession().getAttribute("user");
// 判断用户是否登录
if (user == null) {
// 未登录,跳转到登录页面
res.sendRedirect("/login");
return;
}
// 已登录,放行请求
chain.doFilter(request, response);
}
}
Filter 是 Java Web 开发中一个非常重要的组件,它可以帮助我们实现各种功能,例如用户登录校验、日志记录、字符编码转换等。掌握 Filter 的使用,可以让我们开发出更加安全、稳定、高效的 Web 应用。
最后,希望上文能够帮助各位看官全面了解和掌握 Filter,并在实际项目中灵活运用它来解决各种问题。感谢各位看官的观看,下期见,谢谢~