一、Filter的作用
Filter 是 Servlet API 提供的一个接口,在开发web项目时,过滤器可以在请求到达目标资源之前对请求进行拦截过滤,也可以在响应到达客户端之前先对响应进行拦截过滤,从而实现一些特殊功能。如:实现用户权限级别的创建、过滤敏感词汇、修改请求信息等一些高级功能。
二、Filter基本知识
1.Filter的doFilter()方法
2.Filter的生命周期
Filter的生命周期与Servlet的生命周期类似,其主要生命周期有四个阶段:filter对象的创建(无参构造器)、filter对象的初始化(init方法)、filter执行doFilter()方法、filter对象的销毁(destory())。
Filter的整一个流程都由web服务器操作与管理。init方法和destory方法在应用的整一个过程中,只执行一次。doFilter()方法无论哪个线程访问,只要由该Filter进行过滤,都会执行该Filter的doFilter()方法并且是每过滤一次就执行一次
package com.jinner.filter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
/**
* <T>Filter的生命周期</T>
Filter是应用启动前就创建和初始化
Filter是单例多线程的(单态)
Filter是应用停止时销毁的
doFilter()方法无论哪个线程访问,只要由该Filter进行过滤,都会执行该Filter的doFilter()方法
并且是每过滤一次就执行一次
由于Filter是单态的,为保护其线程的安全性,一般不为Filter添加可修改的成员变量
* */
public class Filter01 extends HttpServlet implements Filter {
private FilterConfig filterConfig;
public Filter01() {
System.out.println("--- 创建Filter01 ---");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("--- 初始化Filter01 ---");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
/**测试Filter的流程*/
System.out.println("执行Filter01 ---before---");
//将请求放行给下一个资源
arg2.doFilter(arg0, arg1);
System.out.println("执行Filter01 ---after ---");
}
public void destory() {
// TODO Auto-generated method stub
System.out.println("--- 销毁Filter01 ---");
}
}
3.Filter的配置
Filter创建后,需要在web.xml文件中进行配置
<filter>元素用于对过滤器的注册
1.<filter-name>过滤器指定一个名字(建议与类名相同)
2.<filter-class>该过滤器的全路径
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。
1.<filter-name>该值必须是在<filter>元素中声明过的过滤器的名字
2.<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式) ,其中/*:对所有请求进行拦截 ;/:不会对动态请求进行拦截,即jsp页面请求,只拦截静态资源请求 。指定拦截则用<servlet-name></servlet-name>
<!-- 注册过滤器 -->
<!-- 当应用存在多个Filter时,其执行顺序与其注册顺序一样 -->
<filter>
<filter-name>Filter01</filter-name>
<filter-class>com.jinner.filter.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.多个Filter执行顺序
web服务器根据Filter在web.xml文件中的注册顺序来决定先调用哪个Filter。
三、Filter在web.xml中多个标签的运用
1.<init-param>
<init-param>标签中放置的元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。如果过滤器不需要指定初始化参数,那么<init-param>元素可以不配置。
package com.jinner.filter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
public class Filter01 extends HttpServlet implements Filter {
private FilterConfig filterConfig;
public Filter01() {
System.out.println("--- 创建Filter01 ---");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
/** FilterConfig的信息指的是web.xml中注册的信息*/
System.out.println("--- 初始化Filter01 ---");
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
//获取Fliter的Name
String filterName = filterConfig.getFilterName();
System.out.println("filterName = "+filterName);
//获得所有初始化的参数值
Enumeration<String> paras = filterConfig.getInitParameterNames();
//遍历
while(paras.hasMoreElements()) {
String name = paras.nextElement();
String value = filterConfig.getInitParameter(name);
System.out.println(name+" = "+value);
}
//获取全局域
ServletContext sc = filterConfig.getServletContext();
System.out.println("ServletContext = "+sc);
//将请求放行给下一个资源
arg2.doFilter(arg0, arg1);
}
public void destory() {
// TODO Auto-generated method stub
System.out.println("--- 销毁Filter01 ---");
}
}
<init-param>
<param-name>userName</param-name>
<param-value>ko</param-value>
</init-param>
<init-param>
<param-name>trueName</param-name>
<param-value>jinner</param-value>
</init-param>
2.<dispatcher>
<dispatcher></dispatcher>中可填写的四个元素:
FORWARD:表示当前过滤器只会拦截一个Servlet通过request.getRequestDispatcher的forward()完成的跳转
INCLUDE:表示当前过滤器只会拦截一个Servlet通过request.getRequestDispatcher的include()完成的跳转
REQUEST:表示当前过滤器只会拦截普通请求,但对于forward()与include()的跳转不进行拦截
ERROR:表示当跳转到指定错误处理页面时,这个请求会被当前过滤器所拦截 (注意:
Servlet中转发的形式:forward和include
forward和include的不同之处: 响应的标准输出流开始时间不一样 )