javaweb学习笔记(二十一):servlet 过滤器

目录

1.实现过滤器

2.Filter实现拦截的原理

3.filter的web.xml配置

4.filter的生命周期


Servlet过滤器就是服务器与客户端请求与响应的中间层组件,在实际项目开发中Servlet过滤器主要用于对浏览器的请求进行过滤处理,将过滤后的请求再转给下一个资源。

通过过滤器,可以实现例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。也可以例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能

1.实现过滤器

在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口即可,此接口定义了三个操作方法:

public void init(FilterConfig filterConfig)

这是Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数

FilterConfig接口的两个方法:(获取初始化参数)
String getInitParameter(java.lang.String name)

Enumeration getInitParameterNames()

String getFilterName():得到filter的名称

public  ServletContext getServletContext():返回Servlet上下文对象的引用。

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)

这个方法完成实际的过滤操作,当客户请求访问过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。

FilterChain参数用于访问后续过滤器。在FilterChain接口中依然定义了一个同样的doFilter()方法,这是因为在一个过滤器后面可能存在着另外一个过滤器,也可能是请求的最终目标(Servlet),这样就通过FilterChain形成了一个“过滤链”的操作

void doFilter(ServletRequest request, ServletResponse response)

public void destroy()

Servlet容器在销毁过滤器实例前调用该方法,这个方法中可以释放Servlet过滤器占用的资源

2.Filter实现拦截的原理

Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下filterdoFilter方法

3.filter的web.xml配置

在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。

在web.xml中配置Servlet和Servlet过滤器,应该先声明过滤器元素,再声明Servlet元素。

 两个或更多个过滤器应用到同一个资源,按照它们在配置文件中显示的先后次序调用它们。

 

其中:

<filter-mapping> : 将过滤器与 servlet 或 URL 模式相关联。

<filter-name> : 指定过滤器的名字,与<filter>中<filter-name>相对应;

<url-pattern> : 指定和过滤器关联的URL,为”/*”表示所有URL;

<dispatcher>,指定过滤器对应的请求方式,可以包含0-4个。可以是 REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST.

REQUEST当用户直接访问页面时,Web容器将会调用过滤器。

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

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

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

<web-app>
<filter>  
    <filter-name>DemoFilter</filter-name>  
    <filter-class>xiaohua.DemoFilter</filter-class>  
    <init-param> <!-- 为过滤器实例提供初始化参数,可以有多个 --> 
        <param-name>param</param-name>  
        <param-value>value</param-value>  
    </init-param>  
 </filter>  
 <filter-mapping>  
    <filter-name>DemoFilter</filter-name>  
    <url-pattern>/*</url-pattern>  <!-- 拦截所有URL -->
    <dispatcher>REQUEST</dispatcher> <!-- 没有配置dispatcher就是默认request方式-->  
    <dispatcher>FORWARD</dispatcher>  
    <dispatcher>ERROR</dispatcher>  
    <dispatcher>INCLUDE</dispatcher>  
 </filter-mapping> 
 
 <filter>   
  	<filter-name>FilterTwo</filter-name>   
  	<filter-class>xiaohua.FilterTwo</filter-class> 
 </filter> 
 <filter-mapping>   
  	<filter-name>FilterTwo</filter-name>   
  	<url-pattern>/xiaohua/*</url-pattern> <!-- 此容器只有在接收到对 /xiaohua目录中的资源的请求时才会应用该过滤器。 -->
 </filter-mapping> 
</web-app>

4.filter的生命周期

和Servlet一样Filter的创建和销毁也是由WEB服务器负责。init方法与destroy方法只会直接一次。

  1. 在应用启动的时候就进行装载Filter类
  2. 容器创建好Filter对象实例后,调用init()方法。
  3. 当用户访问的资源正好被Filter的url-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法
  4. 当应用服务被停止或重新装载了,则会执行Filter的destroy方法,Filter对象销毁。

例:

package xiaohua.HelloFilter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 过滤器,测试
 * @author xiaohua
 *2018-11-13
 */
public class HelloFilter implements Filter{
	
	// 创建实例
	public HelloFilter(){
		System.out.println("1. 创建过滤器实例");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("2. 执行过滤器初始化方法");
		
		// 获取过滤器在web.xml中配置的初始化参数
		String encoding = filterConfig.getInitParameter("encoding");
		System.out.println(encoding);
		
		// 获取过滤器在web.xml中配置的初始化参数 的名称
		Enumeration<String> enums =  filterConfig.getInitParameterNames();
		while (enums.hasMoreElements()){
			// 获取所有参数名称:encoding、path
			String name = enums.nextElement();
			// 获取名称对应的值
			String value = filterConfig.getInitParameter(name);
			System.out.println(name + "\t" + value);
		}
	}

	// 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("3. 执行过滤器业务处理方法");
		
		// 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
		chain.doFilter(request, response);
		
		System.out.println("5. Servlet处理完成,又回到过滤器");
	}

	@Override
	public void destroy() {
		System.out.println("6. 销毁过滤器实例");
	}

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值