Servlet过滤器

过滤器是在请求的预处理和后处理中调用的对象。它主要用于执行过滤任务,例如转换,日志记录,压缩,加密和解密,输入验证等。Servlet过滤器是可插入的,即在web.xml文件中定义了它的条目,如果从web.xml文件中删除了filter的条目,则过滤器将被自动删除,而不需要更改servlet。因此应用的维护成本将更少。

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. FilterChain
FilterChain对象负责调用链中的下一个过滤器或资源。此对象在Filter接口的doFilter方法中传递。FilterChain接口仅包含一个方法:

  • public void doFilter(HttpServletRequest request, HttpServletResponse response) – 它将控制权传递给下一个过滤器或资源。

4. 如何定义过滤器

定义过滤器与servlet定义非常相似,下面来看一下filterfilter-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-patternservlet-nameurl-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:

得到以下结果:
Servlet过滤器

过滤器的简单示例

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

(0)
上一篇 2022年6月6日
下一篇 2022年6月6日

相关推荐

发表回复

登录后才能评论