1.利用Filter来过滤的时候大都是Http请求和Http响应,在doFilter()方法中,参数类是ServletRequest和ServletResponse  ,使用的时候一般需要强制转换为HttpServletRequest和HttpServletResponse  。针对这个问题,可以仿照GenericServlet 的做法,来定义一个HttpFilter,用作所有Filter的父类。

HttpFilter.java

package com.javaweb.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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public abstract class HttpFilter implements Filter {
    @Override
    public void destroy() { }
    /*
     * 原生的doFilter方法,在方法内部把ServletRequest和ServletResponse转为了HttpServletRequest和HttpServletResponse,
     * 并调用了doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain)方法。
     * 若编写Filter的过滤方法不建议直接继承该方法,而建议继承doFilter(HttpServletRequest request,HttpServletResponse response,
     * FilterChain filterchain)方法。
     * */
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterchain)
            throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) req;
        HttpServletResponse response=(HttpServletResponse) resp;
        doFilter(request,response,filterchain);
    }
    //抽象方法,为Http请求定制必须实现的方法。
    public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain) throws IOException, ServletException;
    private FilterConfig filterconfig;
    //不建议子类直接覆盖,若直接覆盖,将可能会导致filterConfig成员变量初始化失败。
    @Override
    public void init(FilterConfig filterconfig) throws ServletException {
        this.filterconfig =filterconfig;
        init();
    }
    //供子类继承的初始化方法,可以通过getFilterConfig()获取FilterConfig对象。
    public void init(){}
    //直接返回init(ServletConfig)的ServletConfig对象。
    public FilterConfig getFilterConfig(){
        return filterconfig;
    }
}

2.理解多个Filter代码的执行顺序

示例代码:

index.html

<body>
<a href="http://localhost:8080/MyWebProject/jspTest/test.jsp">to test jsp page</a>
</body>

test.jsp

<body>
<%
System.out.println("5. Test page");
%>
</body>

过滤器拦截:

filterTest.java

package com.javaweb.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; public class filterTest implements Filter {
@Override
public void destroy() {
System.out.println("destroy...");
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("1. before filterTest's chain.doFilter...");
chain.doFilter(request,response);
System.out.println("2. after filterTest's chain.doFilter...");
} @Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init...");
} }

secondFilter.java

package com.javaweb.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; public class secondFilter implements Filter {
@Override
public void destroy() {
System.out.println("secondFilter's destroy..."); } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("3. before secondFilter's chain doFilter...");
chain.doFilter(request,response);
System.out.println("4. after secondFilter's chain doFilter...");
} @Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("secondFilter's init..."); } }

在web.xml中进行配置:

  <filter>
<filter-name>filterTest</filter-name>
<filter-class>com.javaweb.Filter.filterTest</filter-class>
</filter>
<filter-mapping>
<filter-name>filterTest</filter-name>
<url-pattern>/jspTest/test.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>secondFilter</filter-name>
<filter-class>com.javaweb.Filter.secondFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>secondFilter</filter-name>
<url-pattern>/jspTest/test.jsp</url-pattern>
</filter-mapping>

执行顺序:

index.html页面点击链接时去test.jsp页面,被第一个过滤器filterTest拦截,

①首先执行其中的doFilter()方法,执行方法体中的System.out.println("1. before filterTest's chain.doFilter...");

②之后chain.doFilter(request,response);将拦截传递给下一个过滤器secondFilter,执行其中的doFilter()方法,同样执行方法体中的System.out.println("3. before secondFilter's chain doFilter...");

③接着chain.doFilter(request,response);因为没有过滤器,所以将请求转发到test.jsp,执行<% System.out.println("5. Test page"); %>;

④接下来执行方法体中的System.out.println("4. after secondFilter's chain doFilter...");

⑤最后回到filterTest的doFilter()方法中,执行System.out.println("2. after filterTest's chain.doFilter...");

3.<dispatcher>

<dispatcher></dispatcher>指定过滤器所拦截的资源被Servlet容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认为REQUEST。可以设置多个<dispatcher>子元素来指定Filter对资源的多种调用方式进行拦截。

<dispatcher>子元素可以设置的值及其意义:

REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器将不会被调用。

INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将会被调用,除此之外,该过滤器不会被调用。

FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将会被调用,除此之外,该过滤器不会被调用。

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将会被调用,除此之外,过滤器不会被调用。

最新文章

  1. RabbitMQ安装实践
  2. [ 转载 ] kernel32.BaseThreadInitThunk
  3. Spring RestTemplate: 比httpClient更优雅的Restful URL访问, java HttpPost with header
  4. 用redux构建购物车
  5. 使用multi curl进行http并发访问
  6. 【液晶模块系列基础视频】2.虚拟U盘
  7. 黑马程序员——JAVA基础之数组
  8. Android开发手记(28) Handler和Looper
  9. 使用SQL Server临时表来实现字符串合并处理
  10. Spring-boot中使用@ConditionalOnExpression注解,在特定情况下初始化bean
  11. 上传图片并生成相关缩略图-PHP
  12. WebRTC介绍及简单应用
  13. Python之字符编码与文件操作
  14. MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT
  15. node.js+express,实现RESTful API
  16. R语言-分组统计
  17. update select 多字段
  18. Django项目启动之前执行流程剖析
  19. mysql刷新mysql-bin
  20. Math函数

热门文章

  1. bzoj 4598: [Sdoi2016]模式字符串
  2. Tomcat入门级小白教程
  3. 在通知栏上玩游戏,Steve iOS 游戏实现思路
  4. Beginning and Ending the Speech
  5. 解析XMl文档和字符串
  6. Java的输出方式
  7. Django的模板与母版
  8. POJ_3268 Silver Cow Party 【最短路】
  9. C: City----逆向并查集
  10. Win10远程连接,出现身份验证错误。远程计算机要求的函数不受支持 这可能是由于CredSSP加密Oracle修正 。