1. 前言

Filter—Filter 技术是servlet2.3 新增加的功能。完成的流程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

Filter体现了一种职责琏模式。那么他是如何体现的呢?

2. 职责链模式

在具体的解释这个之前先看看职责链模式的定义:使多个对象都有机会处理请求 ,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一个链,并沿着这条链传递请求,直到有一个对象处理它为止。

对于Filter而言就是,请求传给具体的web资源(比如jsp/servlet)之前要经过Filter的预处理,在web资源处理完成返回给客户端之前也要被Filter处理一遍。就好比下面的这种图

当创建了多个Filter之后,客户端传来一个Request请求,它就面对着这一个Filter链,职责琏模式就体现在这里。这个请求会在这个 Filter链上一个一个被传递下去对它进行预处理,处理完成之后就传给下一个Filter直到最后一个,然后才交给web进行相应的访问和处理。它的 uml图(并不是完成的结构图,只是体现职责琏模式的结构图)如下:

一个Filter接口定义了三个方法:init()(初始化方法);destroy()(销毁方法);doFilter()(核心的职责方法);两个具体类实现了Filter接口:ConcreteFilter1和ConcreteFilter2;

一个FilterChain接口定义了一个方法:doFilter();一个具体的实现类ConcreteFilterChain;

其中FilterChain主要的作用是完成找到下一个Filter。

3. 具体的实现

下面是对于上面结构图的一个简单实现,帮助我们理解一下Filter体现的职责琏模式。

ConcreteFilter1类

[java] view plain copy print?
  1. package com.test.filter;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. /**
  10. * ConcreteFilter1类
  11. * @author pf
  12. *
  13. */
  14. public class ConcreteFilter1 implements Filter {
  15. //  private String encoding;
  16. @Override
  17. public void destroy() {
  18. System.out.println("ConcreteFilter1()的destroy()执行");
  19. }
  20. @Override
  21. public void doFilter(ServletRequest request, ServletResponse response,
  22. FilterChain chain) throws IOException, ServletException {
  23. System.out.println("----ConcreteFilter1()的chain.doFilter()调用之前:对用户请求(request)进行预处理");
  24. //继续执行
  25. //后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
  26. chain.doFilter(request, response);
  27. System.out.println("ConcreteFilter1()的chain.doFilter()调用之后:对服务器响应(response)进行后处理");
  28. }
  29. @Override
  30. public void init(FilterConfig filterConfig) throws ServletException {
  31. //      System.out.println("init开始");
  32. //      this.encoding = filterConfig.getInitParameter("encoding");
  33. //      System.out.println("init得到encoding:" + encoding);
  34. System.out.println("ConcreteFilter1()的init()方法调用");
  35. }
  36. }

ConcreteFilter2类

[java] view plain copy print?
  1. package com.test.filter;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. /**
  10. * 采用Filter统一处理字符集
  11. * @author pf
  12. *
  13. */
  14. public class ConcreteFilter2 implements Filter {
  15. //  private String encoding;
  16. @Override
  17. public void destroy() {
  18. System.out.println("ConcreteFilter2()的destroy()执行");
  19. }
  20. @Override
  21. public void doFilter(ServletRequest request, ServletResponse response,
  22. FilterChain chain) throws IOException, ServletException {
  23. System.out.println("ConcreteFilter2()的chain.doFilter()调用之前");
  24. //      request.setCharacterEncoding(encoding);
  25. //后面有filter继续调用,没有的话就进入到了jsp,一直调用最后
  26. chain.doFilter(request, response);
  27. System.out.println("ConcreteFilter2()的chain.doFilter()调用完成");
  28. }
  29. @Override
  30. public void init(FilterConfig filterConfig) throws ServletException {
  31. //      System.out.println("init开始");
  32. //      this.encoding = filterConfig.getInitParameter("encoding");
  33. //      System.out.println("init得到encoding:" + encoding);
  34. System.out.println("ConcreteFilter2()的init()方法调用");
  35. }
  36. }

web.xml

[html] view plain copy print?
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.4"
  3. xmlns="http://java.sun.com/xml/ns/j2ee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  6. http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  7. <filter>
  8. <filter-name>ConcreteFilter1</filter-name>
  9. <filter-class>com.test.filter.ConcreteFilter1</filter-class>
  10. </filter>
  11. <filter-mapping>
  12. <filter-name>ConcreteFilter1</filter-name>
  13. <url-pattern>*.jsp</url-pattern>
  14. </filter-mapping>
  15. <filter>
  16. <filter-name>ConcreteFilter2</filter-name>
  17. <filter-class>com.test.filter.ConcreteFilter2</filter-class>
  18. </filter>
  19. <filter-mapping>
  20. <filter-name>ConcreteFilter2</filter-name>
  21. <url-pattern>*.jsp</url-pattern>
  22. </filter-mapping>
  23. </web-app>

完成之后启动服务器,我这里是tomcat,会显示如下信息:

说明在启动服务器的时候就会创建我们的Filter对象

随便访问一个页面再次查看console

关闭服务器:说明在关闭服务器的时候销毁创建的Filter对象

从上面的执行结果再来看一下Filter。我们设置了两个Filter,分别是ConcreteFilter1和ConcreteFilter2.按照 我们在web.xml中配置的顺序来执行,先执行了ConcreteFilter1,在执行ConcreteFilter2.

但是注意观察,他们在真正调用chain的doFilter方法之后的调用顺序正好相反了。所以我们从这个结果可以看到Filter的执行顺序是遵循”后 进先出”的原则。现将传来的url按照配置中的顺序进行预处理,但是确实先按照相反的filter顺序执行处理好的请求。

下面是讲他的调用过程画了一个时序图:

3. 总结:

通过上面代码执行的结果来看,Filter很好的实现了职责链模式,对于任何一个请求来讲都有一条Filter链可以处理它,具体是哪一个处理了我们其实并不知道但是在到达servlet之前就是已经给我们处理好了,这样子就很好的做到了对象之间的解耦和。

原文:Filter体现职责链模式

转载于:https://www.cnblogs.com/langtianya/p/5349915.html

Filter体现职责链模式相关推荐

  1. JAVA 设计模式—————— 命令模式和职责链模式

    学习 Netty 前的准备工作!! 这里,还是先来复习一下 OOP (面向对象)的七大原则: 开闭原则:对扩展开放,对修改关闭 里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立. 依赖倒置原 ...

  2. 职责链模式里面必须要知道的事情

    为什么80%的码农都做不了架构师?>>>    职责链模式里面必须要知道的事情 用java web开发的很多同学很容易沉迷于各种框架的使用技巧,而忽略servlet的一些细节.对很多 ...

  3. 漫画设计模式:什么是 “职责链模式” ?

    作者 | 小灰 来源 | 程序员小灰(ID:chengxuyuanxiaohui) -----  第二天  ----- ------------ 在一家公司里,有三个程序员,他们的名字分别是小A.小B ...

  4. C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】

    一.引言 今天我们开始讲"行为型"设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中的例 ...

  5. 职责链模式(chain of responsibility)

    原文地址 一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不 ...

  6. [转]23种经典设计模式的java实现_5_职责链模式

    对于职责链模式,一般是这么定义的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,即--将这些对象连成一条(处理)链,并沿着这条链传递该请求,直到这条链结束同时有一个对象处理它 ...

  7. Java设计模式(备忘录模式-解释器模式-状态模式-策略模式-职责链模式)

    Java设计模式Ⅶ 1.备忘录模式 1.1 备忘录模式概述 1.2 代码理解 2.解释器模式 2.1 解释器模式概述 3.状态模式 3.1 状态模式概述 3.2 代码理解 4.策略模式 4.1 策略模 ...

  8. 重温设计模式(三)——职责链模式(chain of responsibility)

    一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所 ...

  9. 请求的链式处理——职责链模式

    本文转载自 :http://blog.csdn.net/lovelion/article/details/7420891 "一对二","过","过&q ...

最新文章

  1. LeetCode简单题之自除数
  2. FEMS:微生物群落生态学数据挖掘的R包microeco
  3. mysql查询表的列名主键_SQl查询数据库表名、表的列名、数据类型、主键
  4. 一份来自大厂算法工程师的求职宝典
  5. challenging and foundational
  6. SendInput代替了keybd_event
  7. linux 中常用安装配置
  8. apache+php+mysql服务器搭建
  9. 迅捷cad_迅捷套装
  10. xmind8 破解激活教程
  11. MUTA 人力Vocaloid不是梦
  12. C语言:输入日期,计算该日期是该年的第几天。
  13. 龙芯芯片CPU的产品路线说明
  14. GPU服务器与CPU服务器的区别,如何选择GPU服务器
  15. 记一次git pull 错误
  16. linux系统用户默认的shell,linux默认的shell是什么
  17. word如何添加行号_如何将行号添加到Microsoft Word文档
  18. idea修改单行注释颜色
  19. JS--事件(Event)--使用
  20. JNI字段描述符Ljava/lang/String;

热门文章

  1. scala.Enumeration 枚举示例
  2. python requests模块中返回时间elapsed解析
  3. 《云服务器》与《传统服务器》的区别
  4. 遭遇sql server 2005 启动包未能正确加载需要重新安装错误,重装.NET FRAMEWORK经历分析...
  5. Windows下C++多线程同步与互斥简单运用-转
  6. linux 日志优化,Linux —— 日志管理和优化方式
  7. win7 64位操作系统中Oracle 11g + plsql安装教程详解(图解)
  8. 手把手教你用Spring Cloud和Docker构建微服务
  9. Oracle中Sequence序列的使用
  10. JAVA内存释放机制