Tomcat与JavaWeb开发技术详解过滤器第二十章

20.1过滤器简介

过滤器是在Java Servlet2.3中规范定义的,它能够对Servlet容器传给Web组件的ServletRequest对象和ServletReponse对象进行检查和修改。过滤器本身并不生成ServletRequest对象和ServletResponse对象,它只为Web组件提供如下过滤功能:

过滤器能够在Web组件被调用之前检查ServletRequest对象,修改响应头和相应正文的内容,或者对请求进行预处理操作。

过滤器能够在Web组件被调用之后检查ServletResponse对象,修改响应头和响应正文。

过滤器负责过滤的组件可以是Servlet,JSP或HTML文件。




过滤器具有以下特点:

可以检查ServletRequest和ServletResponse对象,并且可以利用ServletRequestWrapper和ServletReponseWrapper包装类来修改ServletRequest和ServletResponse对象。

可以在web.xml文件中为过滤器映射特定的URL。当客户请求访问此URL时,Servlet容器会先出发过滤器工作。

多个过滤器可以被串联在一起,协同为Web组件过滤请求对象和响应对象。

20.2创建过滤器

所有自定义的过滤器类都必须实现javax.servlet.Filter接口。这个接口包含以下三个过滤器必须实现的方法。

init(FilterConfig  config):这是过滤器的初始化方法。Web应用启动时,会先创建包含过滤器配置信息的FileConfig对象,然后创建Filter对象,然后通过该方法的config对象读取web.xml文件中为过滤器配置的初始化参数。

public void init(FilterConfig config) throws ServletException {
System.out.println("NoteFilter :init()");

this.config=config;//把Servlet容器提供的FilterConfig对象传给config成员变量
//读取ipblock初始化参数
ipblock=config.getInitParameter("ipblock");
//读取blacklist初始化参数
blackList=config.getInitParameter("blackList");
}

doFilter(ServletRequest request, ServletResponse response,FilterChain chain):这个方法完成实际的过滤操作。当用户请求访问的URL与过滤器映射的URL匹配时,Servlet容器会先调用过滤器的doFilter方法,chain参数用于访问后续过滤器或者Web组件。

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("NoteFilter:doFilter");
//判断客户IP是否在预定义的拒绝IP地址范围内,
//如果满足这一条件,就直接返回拒绝信息,不再调用后续的NoteServlet组件
if (!checkRemoteIP(request, response)) {
return ;
}
//判断username请求参数表示的姓名是否在黑名单中,
//如果满足这一条件,就直接返回拒绝信息,不再调用后续的NoteServlet组件
if (!checkUsername(request, response)) {
return;
}
//记录响应客户请求的时间
long before=System.currentTimeMillis();
config.getServletContext().log("NoreFiter:before call chain.doFilter()");
//把请求转发给后续的过滤器或者Web组件
chain.doFilter(request, response);
//记录响应客户后的时间
config.getServletContext().log("NoreFiter:after call chain.doFilter()");
long after=System.currentTimeMillis();
StringBuffer name=new StringBuffer();
if (request instanceof HttpServletRequest) {
name=((HttpServletRequest) request).getRequestURL();
}
//记录响应客户所花的时间
config.getServletContext().log("NoreFiter:"+name+":"+(after-before)+"ms");

}

destroy():Servlet容器在销毁过滤器对象前调用该方法,在这个方法中可以释放过滤器占用的资源。

public void destroy() {
System.out.println("NoteFilter:dodestroy");
config=null;

}

Filter的生命周期包含以下几个阶段:初始化阶段,运行时阶段,销毁阶段。

20.3发布过滤器

在发布过滤器时,必须在web,xml文件中加入<filter>元素和<filter-mappig>元素。<filter>元素用来定义一个过滤器,如下:

  <filter>
  <filter-name>NoteFilter</filter-name>
  <filter-class>mypack.NoteFilter</filter-class>
  
  <init-param>
  <param-name>ipblock</param-name>
  <param-value>221.45</param-value>
  </init-param>
  
  <init-param>
  <param-name>blacklist</param-name>
  <param-value>捣蛋鬼</param-value>
  </init-param>
  
  </filter>
  <filter-mapping>
  <filter-name>NoteFilter</filter-name>
  <url-pattern>/node</url-pattern>

  </filter-mapping>

<filter-name>子元素用来指定过滤器的名字,<filter-class>用来指定过滤器的类名,<init-param>子元素为过滤器实例提供初始化参数。 <filter-mapping>用于过滤器映射特定的URL。

20.4串联过滤器:

多个过滤器可以串联起来协同工作,Servlet容器将根据它们在web.xml中定义的先后顺序,依次调用它们的doFilter()方法。假定有两个过滤器串联起来,它们的doFilter()方法均采用如下结构:

code1;

chain.doFilter();

code2;

关于chain.doFilter(request,response)
他的作用是将请求转发给过滤器链上下一个对象。这里的下一个指的是下一个filter,如果没有filter那就是你请求的资源。 一般filter都是一个链,web.xml 里面配置了几个就有几个。一个一个的连在一起 

request -> filter1 -> filter2 ->filter3 -> .... -> request resource.

例如在doFilter()中调用chain.doFilter(request,myWrappedResp);

将名为myWrappedResp的对象传给下一个Filter。


20.4.1包装设计模式

包装设计模式具有以下特点:

*以对客户程序透明的方式,动态地给一个对象附加上更多的功能,或者秀爱这个对象的部分功能

*假定类A是类B的包装类,那么类A和类B具有同样的接口,并且类A拥有类B的实例,类A借助类B的实例来实现接口。

                                                                                                                    2018.07.16





猜你喜欢

转载自blog.csdn.net/qq_40369435/article/details/81067085