标签:ges 方式 断点 response 默认 mod 功能 控制 pack
Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
其顺序图如下(Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。)

过滤器,设计执行流程:
Filter的生命周期
(1)、init(FilterConfig filterConfig)throws ServletException:
与servlet一样(Filter其实也是一个servlet),Filter的创建和销毁是由web服务器负责的。web服务器一启动,就会调用init()方法,完成对象的初始化功能
(注:filter对象只会创建一次,init方法也只会执行一次。)
(2)、destroy():
在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
(3)、doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.(大概的意思是在每次请求/响应时由容器创建)过滤器业务拦截的业务处理方法
程序示例
首先写一个要被访问的servlet,如下:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
 | 
package com.gqx.filter;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class IndexServlet extends HttpServlet {    /**     * 处理用户http request     */    private static final long serialVersionUID = 1L;    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        System.out.println("4、处理用户请求开始!");    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }} | 
然后就是去访问之前需要对请求或响应内容做处理的过滤器
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
 | 
package com.gqx.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;/** * 测试的过滤器 * @author Administrator * */public class HelloFilter implements Filter {    //创建实例    public HelloFilter() {    // TODO Auto-generated constructor stub        System.out.println("1、过滤器用例开始创建了。");    }    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // TODO Auto-generated method stub        System.out.println("2、执行过滤器初始化方法!");    }    //过滤器业务处理方法,在请求到达servlet之前进入此方法处理公用的业务逻辑操作    @Override    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException {        // TODO Auto-generated method stub        System.out.println("3、执行过滤器的业务处理方法!");        //放行(去到Servlet)        chain.doFilter(request, response);             System.out.println("5、Servlet处理完成,又回到Filter了!");    }    @Override    public void destroy() {        // TODO Auto-generated method stub        System.out.println("6、同时过滤器被销毁了!");    }} | 
最后就是要去web.xml中去配置好先关的过滤器设置
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
 | 
    <!-- 过滤器的配置 --><filter>    <!-- filter内部名称 -->    <filter-name>HelloFilter</filter-name>    <!-- 过滤器类的全名 -->    <filter-class>com.gqx.filter.HelloFilter</filter-class></filter><filter-mapping>    <!-- filter内部名称 -->    <filter-name>HelloFilter</filter-name>    <!-- 拦截所有的资源 -->    <url-pattern>/*</url-pattern></filter-mapping> | 
一切都ok了现在我在各个打印语句之前都设置了断点,可以观察到如下图所示的变化

当有多个过滤器的时候,如下
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
 | 
<!-- 过滤器的配置 -->    <filter>        <!-- filter内部名称 -->        <filter-name>HelloFilter</filter-name>        <!-- 过滤器类的全名 -->        <filter-class>com.gqx.filter.HelloFilter</filter-class>    </filter>    <filter-mapping>        <!-- filter内部名称 -->        <filter-name>HelloFilter</filter-name>        <!-- 拦截所有的资源 -->        <url-pattern>/*</url-pattern>    </filter-mapping>         <!-- 配置第二个过滤器 -->    <filter>        <filter-name>HelloFiler2</filter-name>        <filter-class>com.gqx.filter.HelloFilter2</filter-class>    </filter>    <filter-mapping>        <filter-name>HelloFiler2</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping> | 
同理在第一个HelloFilter的doFilter()的方法中写入
| 
 1 
2 
3 
4 
5 
 | 
  System.out.println("3、第一个过滤器:执行过滤器的业务处理方法!");//放行(去到Servlet)chain.doFilter(request, response);System.out.println("5、第一个过滤器:Servlet处理完成,又回到Filter了!"); | 
在HelloFiler2的doFilter()的方法中写入
| 
 1 
2 
3 
 | 
System.out.println("第二个过滤器!");        chain.doFilter(request, response);        System.out.println("第二个过滤器结束了!"); | 
同样在这些语句中设置断点会发现如下结果

这个时候就可以知道服务器启动后,用户去访问,根据xml中的过滤器的先后顺序来执行对应的过滤器,执行其对应的doFilter的方法放行request/response,被放行后他们就进入了第二个过滤器HelloFiler2,被第二个过滤器放行后才会回到对应的servlet,servlet运行完之后,回到第二个过滤器,再回到第一个过滤器。(如下图)
 
(1)、|-- interface Filter 过滤器核心接口
Void init(filterConfig); 初始化方法,在服务器启动时候执行
Void doFilter(request,response,filterChain); 过滤器拦截的业务处理方法
Void destroy(); 销毁过滤器实例时候调用
(2)|-- interface FilterConfig 获取初始化参数信息(方法类似于servletConfig)
String getInitParameter(java.lang.String name)
Enumeration getInitParameterNames()
与servlet同样,在web.xml中配置先关信息
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
 | 
    <filter>    <!-- 配置初始化参数 -->    <init-param>        <param-name>encoding</param-name>        <param-value>UTF-8</param-value>    </init-param>    <init-param>        <param-name>path</param-name>        <param-value>c:/...</param-value>    </init-param>    <filter-name>FilterApi</filter-name>    <filter-class>com.gqx.filter.FilterApi</filter-class></filter><filter-mapping>    <filter-name>FilterApi</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>    | 
(注意:有时候会出现错误 cvc-complex-type.2.4.a: Invalid content was found starting with element 这个时候可以将“http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd”这段话加入到xml文件的"xmlns:xsi="的标签中)
如下:
| 1 | <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd" 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"> | 
然后就是他的过滤器先关的内容了
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
 | 
public class FilterApi implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // TODO Auto-generated method stub        System.out.println("获取过滤器在web.xml中配置的初始化参数!");        String encoding=filterConfig.getInitParameter("encoding");        System.out.println(encoding);        //filterConfig.getFilterName() 获取单个        Enumeration<String> enums=filterConfig.getInitParameterNames();        while (enums.hasMoreElements()) {            //获取对应的参数名称            String name = (String) enums.nextElement();            //获取对应名称的值            String value=filterConfig.getInitParameter(name);            System.out.println(name+"\t"+value);        }    }    @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException {        // TODO Auto-generated method stub     }} | 
启动服务器就会看到控制台打印的先关数据

(3)、|-- interface FilterChain 过滤器链参数;一个个过滤器形成一个执行链;
void doFilter(ServletRequest request, ServletResponse response) ; 执行下一个过滤器或放行
刚才看到的是对所有的请求进行拦截
| 
 1 
2 
3 
4 
 | 
  <filter-mapping>    <filter-name>FilterApi</filter-name>    <url-pattern>/*</url-pattern></filter-mapping> | 
| 
 1 
2 
3 
4 
5 
6 
7 
 | 
@Overridepublic void doFilter(ServletRequest request, ServletResponse response,        FilterChain chain) throws IOException, ServletException {    // TODO Auto-generated method stub    System.out.println("指定过滤器的拦截。。。。。");    chain.doFilter(request, response);} | 
当访问index.jsp的时候,就会出现

当要对多个指定的请求进行拦截时,可以这样写
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
 | 
    <filter>    <filter-name>PontedFilter</filter-name>    <url-pattern>/index.jsp</url-pattern>    <url-pattern>/list.jsp</url-pattern>    <!-- 根据servlet的内部名称拦截    <servlet-name>IndexServlet</servlet-name> -->    <!-- 拦截指定的servlet -->    <url-pattern>/IndexServlet</url-pattern></filter-mapping>      | 
规则有点像servlet的配置
对类型的拦截
| 
 1 
2 
3 
4 
5 
 | 
 <!-- 指定的拦截类型 --><dispatcher>REQUEST</dispatcher>  <!-- 默认的拦截方式 --><dispatcher>FORWARD</dispatcher>  <!-- 拦截转发 --><dispatcher>INCLUDE</dispatcher>  <!-- 拦截包含的页面(RequestDispatcher.include(/page.jsp);    对page.jsp也执行拦截) --><dispatcher>ERROR</dispatcher> | 
默认拦截的类型:(直接访问或者重定向)
<dispatcher>REQUEST</dispatcher>
拦截转发:
<dispatcher>FORWARD</dispatcher>
拦截包含的页面(RequestDispatcher.include(/page.jsp); 对page.jsp也执行拦截)
<dispatcher>INCLUDE</dispatcher>
拦截声明式异常信息:
<dispatcher>ERROR</dispatcher>
类似于如下代码
| 
 1 
2 
3 
4 
5 
 | 
   <error-page>    <error-code>404</error-code>    <exception-type></exception-type>    <location></location></error-page> | 
如下代码示例
| 
 1 
2 
 | 
<url-pattern>/*</url-pattern><dispatcher>FORWARD</dispatcher>  <!-- 拦截转发 --> | 
在ServletTets中写下
| 1 | request.getRequestDispatcher("IndexServlet").forward(request, response); | 
请求的转发就会被拦截住。
标签:ges 方式 断点 response 默认 mod 功能 控制 pack
原文地址:http://www.cnblogs.com/zhangyubao/p/6973794.html