一、过滤器
(一)为什么需要使用过滤器?
过滤器是一种小巧的、可插入的Web组件,它能够对Web应用程序的前期处理和后期处理进行控制,可以拦截请求和响应,查看、提取或者某种方式操作正在客户端和服务器之间进行交换的数据。从应用上讲,它能够:
a、统一设置编码
b、使登入页面更加的安全
c、进行权限控制
(二)过滤器的创建
Servlet过滤器可以当作一个只需要在web.xml文件中配置就可以灵活使用、可以重用的模块化组件。他能够对JSP、HTML、Servlet文件进行过滤。实现一个过滤器需要两个步骤:
a.实现接口:
javax.servlet.Filter;
b.实现三个方法:
I,public void init(FilterConfig config);
II,消亡方法:表示的是过滤器消亡是的动作:
public void destroy();
III,过滤器函数:表示的是过滤器过滤时的动作;
publicoid doFilter(ServletRequest request,ServletResponse response,FilterChain chain);
(三)示例:
1.用添加过滤器的方法解决乱码问题:
首先,编写过滤器Servlet类
package com.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 EncodingFilter implements Filter{
private FilterConfig config = null;
public void init(FilterConfig config) throws ServletException{
config = null;
}
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletEception{
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request,response);
}
public void destroy(){
this.config = config;
}
}
注:如果想换成另外一个编码,如“GBK”,只需要将过滤器中的“UTF-8”全部替换为“GBK”即可。另外,建议与页面的编码格式保持一致。
2.然后,在web.xml文件中配置此过滤器:
……
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<filter-mapping>
……
(四)过滤器的配置步骤讲解:
<!-- 定义Filter --> <filter> <!-- Filter的名字 --> <filter-name>EncodingFilter</filter-name> <!-- Filter的实现类 --> <filter-class>com.filter.EncodingFilter</filter-class> </filter> <!-- 定义Filter拦截的URL地址 --> <filter-mapping> <!-- Filter的名字 --> <filter-name>EncodingFilter</filter-name> <!-- Filter负责拦截的URL 全部以/的请求,如果<url-pattern>/*.action </>,将会以拦截*.action的请求--> <url-pattern>/*</url-pattern> </filter-mapping> 在Servlet2.4中<filter-mapping>中加入了新的标签<dispatcher> ,里面有4个值即:REQUEST, FORWARD,INCLUDE和ERROR,默认不写这个标签的时候是REQUEST,该标签是根据客户端传过来的地址进行过滤,FORWARD方法传过来的request方法可以拦截,<ERROR-PAGE>错误页面传过来的拦截,INCLUDE包含过来的过滤,一般REQUEST传过来的拦截.该标签可以加入多个.
第一,用<filter>元素定义过滤器。
1) <filter>元素有两个必要元素:
[a] <filter-name>元素用来设定过滤器的名字。
[b] <filter-class>元素用来设定过滤器的类型路径。
2) 同时<filter>元素还包括一些可选子要素:<icon>、<description>、<display-name>、<init-param>等,其中使用最多的是<init-param>:
示例:
<filter>
<filter-name>EncodingFilter</filter-name>
<display-name>Encoding Filter</display-name>
<description>no description</description>
<filter-class>com.web.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<init-param>一般与过滤器的初始化函数一起使用,用于参数的初始化。通过FilterConfig.getInitParamenter()函数来获得。第二 ,用<filter-mapping>配置过滤器的映射:
1)在<filter-mapping>元素中,<filter-mapping>用来设定过滤器的名字;
2)配置过滤器的映射最主要的是<url-pattern>元素,用于指定过滤模式。
一般常见的过滤模式有3种:
[a] 过滤所有文件:
<filter-mapping>
<filter-name>FilterName</filter-name>
<!--它的意义是访问所有的文件之前过滤器都要进行过滤,* 符号代表所有文件-->
<url-pattern>/*</url-pattern>
</filter-mapping>
[b]过滤一个或者多个文件目录:
<filter-mapping>
<filter-name>FilterName</filter-name>
<!--它的意义是pathUrl目录下的所有文件进行过滤,<url-pattern>内部如果以"/"开头,"/"则表示是虚拟目录根目录-->
<url-pattern>/pathUrl/*</url-pattern>
[c]过滤指定类型的请求或者文件
<filter-mapping>
<filter-name>FilterName</filter-name>
<!--它的意义是对扩展名以.action为后缀请求文件进行过滤-->
<url-pattern>/*.action</url-pattern>
或者
<filter-mapping>
<filter-name>FilterName</filter-name>
<!--它的意义是对以.jsp为后缀的文件进行过滤-->
<url-pattern>/*.jsp</url-pattern>
过滤器配置需注意:过滤器的初始化和doFilter的调用时机:过滤器的初始化是在服务器运行时自动运行;过滤器的doFilter函数是在Servlet被调用之前被调用的。
补充:运行服务器后就要对过滤器进行初始化,会影响服务器的性能。因为在大型项目中有时候会需要很多很多的过滤器,但是如果每一个过滤器都在服务器中实例化会带来很大的开销,导致启动速度异常慢。
对于此种情况,我们常见的解决方法是把一些简单的验证逻辑交给客户端,如Ajax技术。如果需要对客户进行验证,如果不涉及太核心安全的功能可以在客户端编写程序完成需求。
(五)过滤器的应用场合:
1.获取请求数据并操作。过滤器能够处理请求对象,获得所请求的处理时间,浏览器类型等相关信息,并且能够进行日志操作。
2.性能保障。客户端在发送请求之前可以对内容压缩处理,过滤器在内容传来并在到达Servlet和Jsp页面之前将其解压缩,然后再取得响应内容,并在相应内容发送到客户端之前将其转换压缩格式。过滤器可以设置缓存,对于响应频率比较高的内容可以从缓存中直接提取,然后发送至客户端,提高应用效率。
3.安全保障。过滤器可以从上下文中获取注册信息,当注册信息不合法时,过滤器予以拒绝。同时过滤器还可以根据用户身份的不同进行权限控制。
4.会话处理。过滤器可以通过对会话管理,集中处理内容的显示以及委托处理,使得页面代码可以不考虑会话细节,从而使代码和页面分离。
二、监听器
(一)为什么需要使用监听器:
1)在网站开发中,经常会碰到如下的问题:
i> session(HttpSession)或者application(ServletContentext)中的数据,在创建或者销毁时,能够同时作一些额外的工作。如用户退出登录,应该将其退出时间记录在日志。
ii> 为了将这些额外工作与业务处理分开,最新的Servlet容器能够提供Servlet的监听器,能够用事件机制对session或者application的事件进行处理。
(二)监听器的编写
1.Servlet监听器与AWT监听器很相似,常见监听器接口有四种:
a.ServletContextListener:用于监听ServletContext的变化,如ServletContext的创建和销毁。
b.ServletContextAttributeListener:当ServletContext中的属性发生变化时,可以用它来监听。
c.HttpSessionListener:用来监听HttpSessionListener的变化。
d.HttpSessionAttributeListener:当HttpSession中的属性发生变化时可以用它来进行监听。
(三)使用监听器
1.实现一个监听器的步骤:
a.实现接口。
b.重写与之对应的方法。
2.各种监听器都有自己的方法各种