过滤器是在请求的预处理和后处理中调用的对象。它主要用于执行过滤任务,例如转换,日志记录,压缩,加密和解密,输入验证等。Servlet过滤器是可插入的,即在web.xml
文件中定义了它的条目,如果从web.xml
文件中删除了filter
的条目,则过滤器将被自动删除,而不需要更改servlet。因此应用的维护成本将更少。
注意:与Servlet不同,一个过滤器不依赖于另一个过滤器。
1. 过滤器的用法
- 记录所有传入的请求;
- 记录发出请求的计算机的IP地址;
- 转换;
- 数据压缩;
- 加密和解密;
- 输入验证等;
2. 过滤器的优势
- 过滤器可插拔;
- 一个过滤器不依赖于另一资源;
- 减少维护工作;
3. 过滤器API
像servlet过滤器一样有自己的API。 javax.servlet
包中包含Filter API的三个接口:
Filter
FilterChain
FilterConfig
3.1. Filter
要创建过滤器,必须实现Filter
接口。Filter
接口提供了过滤器的生命周期方法。
方法 | 描述 |
---|---|
public void init(FilterConfig config) |
init() 方法仅被调用一次,用于初始化过滤器。 |
public void doFilter(HttpServletRequest request,HttpServletResponse response, FilterChain chain) |
每当用户请求过滤器映射到的任何资源时,都会调用doFilter() 方法,该方法用于执行过滤任务。 |
public void destroy() |
当从服务中删除过滤器时调用destroy() 方法,仅调用一次。 |
3.2. FilterChainFilterChain
对象负责调用链中的下一个过滤器或资源。此对象在Filter
接口的doFilter
方法中传递。FilterChain
接口仅包含一个方法:
public void doFilter(HttpServletRequest request, HttpServletResponse response)
– 它将控制权传递给下一个过滤器或资源。
4. 如何定义过滤器
定义过滤器与servlet定义非常相似,下面来看一下filter
和filter-mapping
的元素如何配置。
<web-app> <filter> <filter-name>...</filter-name> <filter-class>...</filter-class> </filter> <filter-mapping> <filter-name>...</filter-name> <url-pattern>...</url-pattern> </filter-mapping> </web-app>
对于映射过滤器,可以使用url-pattern
或servlet-name
。 url-pattern
元素优于servlet-name
元素,即可以应用于servlet,JSP或HTML。
5. 过滤器的简单示例
在此示例中,仅显示在请求的后处理之后自动调用过滤器的信息。
启动Eclipse,创建一个动态Web项目:HelloFilter,完整的目录结构如下所示:
文件:index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>过滤器 - By xntutor.com</title> </head> <body> <a href="servlet1">过滤调用示例</a> </body> </html>
文件:MyFilter.java
package com.xntutor.filter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.*; public class MyFilter implements Filter{ public void init(FilterConfig arg0) throws ServletException {} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { PrintWriter out=resp.getWriter(); out.print("filter is invoked before"); chain.doFilter(req, resp);//sends request to next resource out.print("filter is invoked after"); } public void destroy() {} }
文件:HelloServlet.java
package com.xntutor.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.*; public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print("<br>welcome to servlet<br>"); } }
文件:web.xml
要定义过滤器,必须像servlet一样定义web-app
下的filter
元素。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>HelloFilter</display-name> <servlet> <servlet-name>s1</servlet-name> <servlet-class>com.xntutor.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>s1</servlet-name> <url-pattern>/servlet1</url-pattern> </servlet-mapping> <filter> <filter-name>f1</filter-name> <filter-class>com.xntutor.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>f1</filter-name> <url-pattern>/servlet1</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
启动Tomcat服务器,打开浏览器访问下面URL:
得到以下结果:
6. 过滤器的其他应用示例
6.1. 仅通过过滤器发送响应的示例
import java.io.*; import javax.servlet.*; public class MyFilter implements Filter{ public void init(FilterConfig arg0) throws ServletException {} public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { PrintWriter out=res.getWriter(); out.print("<br/>this site is underconstruction.."); out.close(); } public void destroy() {} }
6.2. 单页访问者计数示例
import java.io.*; import javax.servlet.*; public class MyFilter implements Filter{ static int count=0; public void init(FilterConfig arg0) throws ServletException {} public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { PrintWriter out=res.getWriter(); chain.doFilter(request,response); out.print("<br/>Total visitors "+(++count)); out.close(); } public void destroy() {} }
6.3. 在过滤器中检查总响应时间的示例
import java.io.*; import javax.servlet.*; public class MyFilter implements Filter{ static int count=0; public void init(FilterConfig arg0) throws ServletException {} public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { PrintWriter out=res.getWriter(); long before=System.currentTimeMillis(); chain.doFilter(request,response); long after=System.currentTimeMillis(); out.print("<br/>Total response time "+(after-before)+" miliseconds"); out.close(); } public void destroy() {} }
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/264033.html