11.9.16.Filter(过滤器)
作用:过滤器在请求到达 Servlet 之前和响应返回给客户端之后,进行某些处理,如日志记录、权限验证等。
11.9.16.1.Filter(过滤器)概述
Filter(过滤器)是 Java Servlet API 中的一个接口,用于在请求到达 Servlet 之前、响应离开 Servlet 之后进行处理。
过滤器可以用于多种用途,如请求和响应的修改、日志记录、身份验证、授权、输入验证、请求重定向等。
过滤器的作用是在Web 应用中对请求和响应进行拦截处理,它为开发者提供了一种方式,在请求和响应生命周期的不同阶段,进行一些特定的处理逻辑。
11.9.16.2.什么是 Filter
Filter 接口定义了三个主要方法:
1)init():初始化过滤器。
2)doFilter():执行过滤操作。
3)destroy():销毁过滤器,释放资源。
过滤器可以用于以下场景:
1)请求预处理:在请求到达 Servlet 之前,进行一些处理(例如记录日志、检查身份验证信息)。
2)响应后处理:在响应返回客户端之前,修改响应内容(例如添加响应头、压缩响应内容)。
3)请求转发或重定向:可以在过滤器内处理请求,决定是否继续向下传递请求,或者重定向/转发到其他页面。
11.9.16.3.Filter 接口
1)初始化方法 - init()
init() 方法在过滤器初始化时被调用。它只会被调用一次,用于做一些初始化操作,例如读取配置文件,建立数据库连接等。
| public void init(FilterConfig filterConfig) throws ServletException { // 过滤器的初始化操作 } | 
2)过滤方法 - doFilter()
doFilter() 是过滤器的核心方法。
每当请求到达 Servlet 时,doFilter() 会被调用。
过滤器可以在该方法内修改请求或响应,并决定是否将请求传递给下一个过滤器或目标资源(例如 Servlet)。
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 处理请求,通常在此处进行请求预处理或响应后处理 // 放行请求,继续向下执行过滤器链 chain.doFilter(request, response); // 在此处可以做响应后处理 } | 
3)销毁方法 - destroy()
destroy() 方法在过滤器销毁时被调用。通常用于释放资源,例如关闭数据库连接、释放内存等。它只会被调用一次。
| public void destroy() { // 清理过滤器所占用的资源 } | 
11.9.16.4.Filter 的使用
1)配置 Filter
为了使用过滤器,需要将过滤器注册到 web.xml 配置文件中(对于 Servlet 3.0 及以上版本,也可以使用注解方式进行配置)。
a.在 web.xml 中配置 Filter
| <filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/myServlet</url-pattern> </filter-mapping> <filter>:定义过滤器的名称和类。 <filter-mapping>:定义过滤器应用的 URL 模式,可以是 url-pattern 或 servlet-name。 | 
b.使用注解配置 Filter(适用于 Servlet 3.0 及以上版本)
| @WebFilter("/myServlet") public class MyFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { // 初始化操作 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 预处理请求 chain.doFilter(request, response); // 响应后处理 } public void destroy() { // 销毁操作 } } | 
使用 @WebFilter 注解来标记过滤器类。
urlPatterns 参数用于指定过滤器适用的 URL 模式。
11.9.16.5.Filter 的应用场景
1)日志记录
可以使用过滤器来记录所有请求和响应的信息。例如,记录每次请求的访问路径、请求参数、响应状态等信息。
| @WebFilter("/*") public class LoggingFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("Request URI: " + ((HttpServletRequest) request).getRequestURI()); 
 chain.doFilter(request, response); 
 System.out.println("Response Status: " + ((HttpServletResponse) response).getStatus()); } } | 
2)身份验证和授权
过滤器常用于身份验证和授权。如果请求没有合法的身份验证信息,过滤器可以直接拒绝请求,或者重定向到登录页面。
| @WebFilter("/secure/*") public class AuthenticationFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; 
 // 检查用户是否已登录 if (httpRequest.getSession().getAttribute("user") == null) { // 如果未登录,重定向到登录页面 ((HttpServletResponse) response).sendRedirect("login.jsp"); return; } 
 chain.doFilter(request, response); } } | 
3)输入验证
过滤器还可以用于验证用户提交的数据是否合法。如果数据不合法,过滤器可以拦截请求并返回错误信息。
| @WebFilter("/submitForm") public class InputValidationFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String username = request.getParameter("username"); if (username == null || username.trim().isEmpty()) { // 如果用户名为空,返回错误信息 ((HttpServletResponse) response).sendError(HttpServletResponse.SC_BAD_REQUEST, "Username cannot be empty"); return; } 
 chain.doFilter(request, response); } } | 
4)响应压缩
可以使用过滤器对响应内容进行压缩,从而减少数据的传输量,提高页面加载速度。
| @WebFilter("/*") public class CompressionFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { CompressionResponseWrapper responseWrapper = new CompressionResponseWrapper((HttpServletResponse) response); 
 chain.doFilter(request, responseWrapper); 
 responseWrapper.finishResponse(); } } | 
5)请求重定向
过滤器可以根据请求的特定条件进行重定向,控制请求流向。
| @WebFilter("/*") public class RedirectFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String userAgent = ((HttpServletRequest) request).getHeader("User-Agent"); 
 if (userAgent != null && userAgent.contains("Mobile")) { // 如果是手机访问,重定向到移动页面 ((HttpServletResponse) response).sendRedirect("mobileHome.jsp"); } else { chain.doFilter(request, response); } } } | 
