Filter内容
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:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将会被调用,除此之外,过滤器不会被调用。
上一篇: 基于Gecko内核的简单浏览器实现
下一篇: 实现简单的粒子连线