过滤器、拦截器、监听器

原文:https://www.zhihu.com/question/35225845/answer/61876681

从设计模式的角度分析它们的不同。

过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。

拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。

监听器(Listener):当一个事件发生的时候,你希望获得这个事件发生的详细信息,而并不想干预这个事件本身的进程,这就要用到监听器。



更形象一点表示:

过滤器:只想要在一堆东西里面选个B

拦截器:把水流变小点,把鱼都拦住!顺便发个电

监听器:题主一定会说上面是个水利工程,其实发电的原理是这样的。。



设计模式的命名都跟真实的场景有密切相关性,只要理解了命名,就理解了模式。

不妨以Java举例:

Filter:

// 填充100个带有随机字母标签的球
List<String> array = new ArrayList<>();
Random r = new Random();
String[] balls = new String[]{"A", "B", "C"};
for (int i = 0; i < 100; i++)
  array.add(balls[r.nextInt(3)]);

// 只拿出B的来。不明白的自行学习Java 8
array = array.stream().filter(ball -> ball.equals("B")).collect(Collectors.toList());

Interceptor:

class River {
  // 流量
  int volume;

  // 总鱼数
  int numFish;
}

class PowerGenerator {
  double generate (int volume) {
    // 假设每一百立方米水发一度电
    return volume / 100;
  }
}

interface Interceptor {
  void intercept (River river);
}

class SomeInterceptor implements Interceptor {
  PowerGenerator generator = new PowerGenerator();

  @Override
  public void intercept (River river) {
    // 消耗了1000立方米水来发电
    int waterUsed = 1000;

    // 水量减少了1000。请不要跟我讨论水电站原理的问题,
    // 我就那么一比方
    river.volume -= waterUsed;

    // 发电
    generator.generate (waterUsed);

    // 拦截所有的鱼
    river.numFish = 0;
  }
}

class RiverController {
  Interceptor interceptor;

  void flow(River river) {
    // 源头积累下来的水量和鱼
    river.volume += 100000
    river.numFish += 1000

    // 经过了大坝
    interceptor.intercept(river);

    // 下了点雨
    river.volume += 1000
  }

  void setInterceptor (Interceptor interceptor) {
    this.interceptor = interceptor
  }
}

class Main {
  public static void main (String args[]) {
    RiverController rc = new RiverController;
    Interceptor inter = new SomeInterceptor();

    // 这一步通常叫做控制反转或依赖注入,其实也没啥子
    rc.setInterceptor(inter);

    rc.flow(new River());
  }
}

 Listener:

// 监听器
interface BedListener {
  // 监听器在参数中收到了某个事件,而这个事件往往是只读的
  // 监听器的方法名通常以"on"开头
  void onBedSound (String sound);
}

class Neighbor {
  BedListener listener;

  // 依然是所谓控制反转
  setListener (BedListener listener) {
    this.listener = listener;
  }

  void doInterestingStuff () {
    // 根据当地法律法规,部分内容无法显示

    // 将事件发送给监听器
    listener.onBedSound("嘿咻");
    listener.onBedSound("oyeah");
  }
}

class Main {
  public static void main (String args[]) {
    Neighbor n = new Neighbor();
    n.setListener (sound -> generatePower());
    n.doInterestingStuff();
  }

  private static void generatePower() {
    // 根据当地法律法规,部分内容无法显示
  }
}

在真实使用中,很多人,不管是新手还是老手会犯的一个错误是,在不该改变对象状态的时候强制改变它,或者在应该传入只读参数时传入了可变参数。

上面的例子中,Filter的例子是JDK提供的函数,如果你在这里改变了对象的状态(当然例子里的String类型本来就不可以改变),就违背了filter的约定。

同样的,在Listener中不管是传入了可变的对象,或是对该对象进行了修改,都是违背设计模式约定的做法,会给其他读代码的人造成困扰。

而Interceptor几乎可以对流程做任何事情,所以没有什么特别要注意的地方,用这一类接口的时候仔细读文档,设计这一类接口的时候仔细写文档吧。

来源:知乎

原文地址:https://www.cnblogs.com/wkcode/p/9608267.html

时间: 2024-10-19 19:39:55

过滤器、拦截器、监听器的相关文章

SpringBoot 过滤器, 拦截器, 监听器 对比及使用场景

1. 过滤器 (实现 javax.servlet.Filter 接口) ① 过滤器是在web应用启动的时候初始化一次, 在web应用停止的时候销毁. ② 可以对请求的URL进行过滤, 对敏感词过滤, ③ 挡在拦截器的外层 ④ Filter 是 Servlet 规范的一部分 2. 拦截器 (实现 org.springframework.web.servlet.HandlerInterceptor 接口) ① 不依赖Spring容器, 可以使用 Spring 容器管理的Bean ② 拦截器通过动态代

过滤器/拦截器/监听器 —— Filter、Interceptor、Listener

一.Filter的功能 filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个"servlet chaining"(servlet 链). 一个Filter包括: 1)在servlet被调用之前截获; 2)在servlet被调用之前检查

过滤器 拦截器 区别

转 http://www.cnblogs.com/wangyuyu/archive/2013/07/02/3167354.html 1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用 4.拦截器可以访问action上下文.值栈里的对象,而过滤器不能 5.在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

Java中的过滤器,拦截器,监听器---------简单易懂的介绍

过滤器: 过滤器其主要特点在于:取你需要的东西,忽视那些不需要的东西!在程序中,你希望选择中篇文章中的所有数字,你就可以针对性的挑选数字! 拦截器: 拦截器其主要特点在于:针对你不要的东西进行拦截,比如说,在一个BBS里面你希望人家不要留“小乌鸦”的这个词,那你就可能采用拦截器! 监听器: 是一个事件处理过程,这个过程的取舍,可以让你的代码成为过滤器,还是成为拦截器~~~比如,你想监听一段用户的数据中有没有1有的话就打印111!这就需要程序都监听用户输入的东西了!if(***..equls('1

浅谈Struts2拦截器的原理与实现

拦截器与过滤器           拦截器是对调用的Action起作用,它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式,很多业务逻辑都是靠拦截实现的,比如校验,验证登录权限(比如下载时跳转到登陆页面)等等.     过滤器是对整个的请求过程起作用!换句话说就是拦截器没有过滤器的范围广.过滤器是在java web中,你传入的request,response提前过滤掉一些信息

过滤器、监听器、拦截器的区别

1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request.Response)统一设置编码,简化操作:同时还可进行逻辑判断,如用户是否已经登陆.有没有权限访问该页面等等工作.它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用

java过滤器、监听器、拦截器机制

一.过滤器 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. 它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理.使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Se

过滤器、监听器、拦截器配置

一.过滤器.监听器配置在web.xml配置文件中,拦截器则不一定,可通过 web.xml加载配置拦截器的文件: 1.在DispatcherServlet的初始化过程中,Spring会在web应用的WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml的配置文件,     生成文件中定义的bean.这些bean会覆盖在全局范围(global cope)中定义的同名的bean.如果servletName-servlet.xml不在默认路径下必须显示指定. 2. 在 XXX

Servlet,过滤器,监听器,拦截器的区别

<因时间仓促,引用别人的博文> 想起struts2和struts1的区别的时 候,发现为什么struts1要用servlet,而struts2要用filter呢?一时又发现,servlet和filter有什么区别呢?于是看 了看web.xml,一时又发现,咦,servlet.filter.listener?还有个interceptor? 慢慢来吧,需要补课的地方还有很多很多呀.初学的时候都不知道他们存在呢.呵呵. 下面从几个方面阐述一下题目中四个概念的区别与联系: 1.概念 2.生命周期 3.

Java中的拦截器、过滤器、监听器

过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts2的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts2的action前统一设置字符集,或者去除掉一些非法字符 拦截器,是在面向切面编程(AOP)的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器