欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Filter内容

程序员文章站 2022-05-18 22:55:59
1.利用Filter来过滤的时候大都是Http请求和Http响应,在doFilter()方法中,参数类是ServletRequest和ServletResponse ,使用的时候一般需要强制转换为HttpServletRequest和HttpServletResponse 。针对这个问题,可以仿照G ......

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>

执行顺序:

Filter内容

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