Servlet 认识过滤器

过滤器简介

Servlet过滤器是一种Web组件(本质也是java类),它们拦截请求和响应,以便查看、提取或以某种方式操作客户端和服务器之间交换的数据。

请求和响应优先判断是否有过滤器存在,如果有过滤器,先进入过滤器,在从过滤器到目标资源。

过滤器并不是必须把请求传送到下一个过滤器,它可以根据处理结果直接给客户端发送响应,也可以将请求转发给另外一个目标资源。

所有的过滤器在开发中必须实现javax.servlet.Filter接口,并且提供一个公开的不带参数的构造方法。接口定义了init()、 doFilter()和destroy() 3个方法,和Servelt接口类似,这3个方法分别对应Servlet过滤器生命周期中的初始化、响应和销毁3个阶段。
注意:如果存在过滤链(像糖葫芦一样,即经过多个过滤器),那么在每个过滤器中的 doFilter()方法中都要调用链接对象(FilterChain)的doFilter()方法。

在doFilter()方法中可以通过对ServletRequest的操作在Servlet运行之前改变Web请求的头信息或内容,通过对ServletResponse的操作在Servlet运行之后改变响应结果。
在使用doFilter()方法前可以通过对request修改请求内容,但这时不能对响应内容进行修改(因为此时响应内容还不存在,为空)。在doFilter()方法之后可以对响应内容进行修改(此时servlet或后一个过滤器响应给到当前过滤器),此时也可以修改请求但没有意义,因为请求已经处理完毕。
注意:过滤器的一个实例可以同时服务于多个请求,即多个或全部请求可以通过一个过滤器过滤。

public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException,ServletException {
	//before doFilter() 可以对请求req进行修改,但不能修改响应res
	chain.doFilter(req,res);//将请求递给下一个过滤器或者目标资源
	//after doFilter() 可以对响应res进行修改。也可以修改请求req(但无意义)
}

过滤器的部署

在创建过滤器之后必须将它添加到部署描述符中,这样容器才会将过滤器投入到服务中去。
有两种过滤器的部署方法
一、利用xml文件部署:
部署过滤器分为两部分。
1、 声明过滤器:元素
其中,<description>元素为filter指定一个文本描述;
<display-name>元素为filter指定一个简短的名字,这个名字可以被一些工具所显示;
<icon>元素为filter指定一个图标,在图形界面中可用它表示该filter;
<filter-name>元素为过滤器指定一个名字,该元素不能为空;
< filter-class>元素用于指定过滤器完整限定类名;

2、设置过滤器映射:
<filter-mapping>元素用于指定过滤器关联的URL样式或者Servlet。

<filter-name>子元素的值必须是元素中声明过的过滤器的名字。

子元素<url-pattern>和<servlet-name>可以选择一个设置。

<url-pattern>元素为过滤器关联的URL,<servlet-name>元素为过滤器对应的Servlet,当用户访问<url-pattern>元素上指定的资源或<servlet-name>元素指定的Servlet时,这个过滤器才会被容器调用。

最多可以有4个<dispatcher>元素,<dispatcher>元素指定过滤器对应的请求方式,有4种请求方式:REQUEST、INCLUDE、FORWARD和ERROR,默认是REQUEST。

REQUEST:当用户直接访问页面时,Web容器将调用过滤器。除此之外,不会调用该过滤器。
INCLUDE:用户访问的目标资源是通过RequestDispatch的include()方法访问时,容器会调用过滤器。除此之外,不会调用该过滤器。
FORWARD:用户访问的目标资源是通过RequestDispatch的forward()方法访问时,容器会调用过滤器。除此之外,不会调用该过滤器。
ERROR:在目标资源是通过声明式异常处理机制调用时,容器会调用过滤器。
注意:可以同时存在多种请求方式。

<filter>
	<description>...</description>  <!--为filter指定一个文本描述-->
	<display-name>...</display-name> <!--元素为filter指定一个简短的名字,这个名字可以被一些工具所显示-->
	<icon>...</icon> <!--为filter指定一个图标,在图形界面中可用它表示该filter-->
	<filter-name>filtername</filter-name> <!--为过滤器指定一个名字,该元素不能为空-->
	<filter-class>class</filter-class> <!--用于指定过滤器完整限定类名-->
	
	<init-param> <!--为过滤器指定初始化参数-->
		<param-name>name</param-name><!--指定参数的名字-->
		<param-value>value</param-value><!--指定参数的值-->
	</init-param>
</filter>

<filter-mapping>
	 <filter-name>filtername</filter-name><!--和上面那个filtername要一致-->
	 <url-pattern>url</url-pattern> <!--为过滤器关联的URL-->
	 <dispatcher>REQUEST</dispatcher><!--默认为REQUEST-->
	 <dispatcher>INCLUDE</dispatcher>
	 <dispatcher>FORWARD</dispatcher>
	 <dispatcher>ERROR</dispatcher>
</filter-mapping>

注意:在映射过滤器时,应高度重视元素<servlet-mapping>的顺序。一旦顺序颠倒,完全可能形成与设计时完全不同的结果。

二、利用@WebFilter注解
还可以用@WebFilter注解来部署:
@WebFilter用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。这些属性中value、urlPatterns、servletNames三者必需至少包含一个,且value和urlPatterns不能共存,如果同时指定,通常忽略value的取值;其他属性均为可选属性。

过滤器常用的场景

1、在Web应用中,常要求用户注册成功后才能使用。有时用户在注册时输入不合法。在过滤器中拦截客户端请求,获得输入的参数数据,对输入参数数据的合法性进行校验,将不合法的请求重新定位到一个错误页面。

2、使用过滤器改变请求的编码:
当没有指定request的编码方式时,从客户端得到的数据是ISO-8859-1编码的。如果客户端提交的数据中包含中文,那么使用request. getParameter()得到提交的参数值会显示为乱码。
解决办法之一就是开发一个过滤器对请求进行统一编码,一次性解决所有页面请求的编码转换问题。
这个过滤器的顺序不能放错(不然没效果)。

总的来说,过滤器主要对客户端的请求和响应进行统一处理。常见过滤器有对用户请求进行统—认证、对用户发送的数据进行过滤或替换、对用户的访问请求进行记录和审核、对响应内容进行压缩、对请求和响应进行加密解密处理、触发资源访问事件等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值