Servlet(二)servlet过滤器filter

.1)什么是过滤器

       servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

.2)filter工作原理

先来看看filter原理图:

https://img-my.csdn.net/uploads/201604/07/1459996798_8945.png

        当客户端向Web资源发出请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请求数据进行检查或改动,并依次通过过滤器链,最后把请求/响应交给请求的Web资源处理。请求信息在过滤器链中可以被修改,也可以根据条件让请求不发往资源处理器,并直接向客户机发回一个响应。当资源处理器完成了对资源的处理后,响应信息将逐级逆向返回。同样在这个过程中,用户可以修改响应信息,从而完成一定的任务。

在上面的描述中,提到了过滤链(FilterChain)的问题,需要特别指出的是,多个过滤器执行的顺序是由配置在web.xml中的顺序决定的。

.3)filter的生命周期
        Filter的创建和销毁是由WEB服务器负责的,在应用启动的时候装载Filter类并创建对象实例,然后调用init()方法,接着被Web容器保存进应用级的集合容器中,等待用户访问资源;当用户访问的资源正好被Filter的url-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了);当应用服务被停止或重新装载了,则会执行Filter的destroy方法,Filter对象销毁。
注意:init方法与destroy方法只会直接一次。

.4)filter API

servlet对过滤器提供了3个接口,分别是:filter,filterChain,filterConfig

filter接口,主要提供下面3个方法:

      init()  Init 方法在 Filter 生命周期中仅执行一次,web 容器在创建了filter对象实例后调用
     destory()  在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
     doFilter() Filter 链的执行 控制

filterChain接口,提供了doFilter()方法,主要进行链的控制

filterConfig接口,检索过滤器名、初始化参数以及活动的Servlet上下文 ,提供下面4个方法:

     getFilterName() 返回web.xml部署文件中定义的该过滤器的名称。
     getServletContext()  返回调用者所处的servlet上下文。
     getlnitParameter()返回过滤器初始化参数值的字符串形式,当参数不存在时,返回nul1.name是初始化参数名。   
     getlnitParameterNames()  以Enumeration形式返回过滤器所有初始化参数值,如果没有初始化参数,返回为空。   

.5)使用场景

过滤器主要使用场景有以下几点:

    (1)用户认证与授权管理
    (2)统计web应用的访问量,和访问的命中率,报告
    (3)实现web应用的日志、乱码处理功能
 (4)实现数据压缩功能
 (5)对传输的数据进行加密

    (6)实现XML文件的XSLT转换

.6)filter使用

创建HelloServlet,有请求就输出Hello字符串

public class HelloServlet extends HttpServlet {

	private static final long serialVersionUID = -1430231096992328970L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		PrintWriter pw=resp.getWriter();
		pw.print("Hello");
	}

}
创建EncodingFilter,过滤servlet请求并设置编码为utf-8

public class EncodingFilter implements Filter {

	private String encoding;

	// 项目结束时就已经进行销毁
	public void destroy() {
		System.out.println("do destroy()");
		encoding = null;
	}

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("before encoding " + encoding + " filter!");
		req.setCharacterEncoding(encoding);
		chain.doFilter(req, resp);
		System.out.println("after encoding " + encoding + " filter!");
	}

	// 项目启动时就已经进行读取
	public void init(FilterConfig config) throws ServletException {
		System.out.println("init HelloFilter");
		encoding = config.getInitParameter("encoding");
	}

}
web.xml配置servlet及filter

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>JustT</display-name>
	<servlet>
		<servlet-name>HelloWorld</servlet-name>
		<servlet-class>com.test.servlet.HelloServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>HelloWorld</servlet-name>
		<url-pattern>/HelloWorld</url-pattern>
	</servlet-mapping>
	
	 <filter>  
        <filter-name>setCharacterEncoding</filter-name>  
        <filter-class>com.test.servlet.filter.EncodingFilter</filter-class>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>utf-8</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>setCharacterEncoding</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping> 
</web-app>

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值