Tomcat与JavaWeb开发技术详解过滤器

过滤器简介

过滤器是在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组件过滤请求对象和响应对象。

创建过滤器

所有自定义的过滤器类都必须实现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的生命周期包含以下几个阶段:初始化阶段运行时阶段销毁阶段

发布过滤器

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

  <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。

串联过滤器:

多个过滤器可以串联起来协同工作,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。

包装设计模式

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

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

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

发布了69 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40369435/article/details/91910504
今日推荐