参考:
https://www.jianshu.com/p/c4ef6d232e8d
https://www.jb51.net/article/96496.htm
1.servlet:servlet 是一种运行服务器端的 java 应用程序,具有独立于平台和协议的特性,并且可以动态的生成 web 页面,它工作在客户端请求与服务器响应的中间层。
2.filter:filter 是一个可以复用的代码片段,可以用来转换 HTTP 请求、响应和头信息。Filter 不像 Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求或者响应。
3.listener:监听器。通过 listener 可以监听 web 服务器中某一个执行动作,并根据其要求作出相应的响应。通俗的说监听器就是在 application
,session
,request
三个对象创建、销毁或者在其中添加、修改、删除属性时自动执行代码的功能组件。
4.interceptor:动态代理就是拦截器的简单实现,在调用方法前打印出字符串或者做其它业务逻辑的操作,也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。
5.aspect:可以自定义切入的点,有方法的参数,但是拿不到 http 请求,可以通过其他方式如 RequestContextHolder 获得。
6.servlet、filter、listener 配置在 web.xml 中,spring 的 interceptor 配置到 spring.xml 中。
7.Filter,Interceptor,Aspect 实际上都是对 AOP 的具体实现。都是对业务逻辑的提取,都可以实现权限检查,日志记录。不同的是使用的范围不同,规范不同,深度不同。
8.Filter 是 java web 里面的,获取不到 spring 里面 Controller 的信息。Interceptor、Aspect 是和 spring 相关的,所以能获取到 Controller 的信息。
web.xml 的加载顺序是:context-param -> listener -> filter -> servlet
另:
servlet
(1)创建并返回一个包含基于客户请求性质的动态内容的完整的 html 页面
(2)创建可嵌入到现有的 html 页面中的一部分 html 页面(html片段)
(3)读取客户端发来的显示或隐藏数据
(4)通过状态代码和响应头向客户端发送隐藏数据。
(5)与其他服务器资源(包括数据库和 java 的应用程序)进行通信
filter
(1)filter 能够在一个请求到达 servlet 之前预处理用户请求,也可以在离开 servlet 时处理 http 响应
(2)根据程序需要修改请求和响应
listener
servlet 2.4 规范中提供了 8 个 listener 接口,可以将其分为三类,分别如下:
(1)与 ServletContext
有关的接口。包括:ServletContextListener、ServletContextAttributeListener
(2)与 HttpSession
有关的接口。包括:HttpSessionListner、HttpSessionAttributeListener、HttpSessionBindingListener、 HttpSessionActivationListener
(3)与 ServletRequest
有关的接口,包括:ServletRequestListner、ServletRequestAttributeListener
1.servlet
servlet 流程是短的,url 传来之后,就对其进行处理,之后返回或转向到某一自己指定的页面。它主要用来在业务处理之前进行控制。
2.filter
流程是线程性的,url 传来之后,检查之后,可保持原来的流程继续向下执行,被下一个 filter, servlet 接收等,而 servlet 处理之后,不会继续向下传递。
filter 功能可用来保持流程继续按照原来的方式进行下去,或者主导流程,而 servlet 的功能主要用来主导流程。可以将 Filter 看成是 servlet 的一个补充。
filter 可认为是 servlet 的一种“变种”,它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理,是个典型的处理链。
它与 Servlet 的区别在于:它不能直接向用户生成响应。
完整的流程是:Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对服务器响应进行后处理。
3.匹配规则
当一个请求发送到 servlet 容器的时候,容器先会将请求的 url 减去当前应用上下文的路径作为 servlet 的映射 url,比如访问 http://localhost/test/aaa.html,应用上下文是 test,容器会将 http://localhost/test 去掉,将剩下的 /aaa.html 部分拿来做 servlet 的映射匹配,也就是拿这剩下的部分与 web.xml 中配置的 servlet 的 url-pattern 进行匹配。
注意:这个映射匹配过程是有一定的规则的,而且每次匹配最终都只匹配一个 servlet,这点和 filter 不同。当一個 servlet 匹配成功后就不会在往下去匹配了。
精确路径匹配:
例子:比如 servlet A 的 url-pattern 为 /test,servlet B 的 url- pattern 为 /* ,这个时候,如果访问的url为 http://localhost/test ,
这个时候容器就会先进行精确路径匹配,发现 /test 正好被 servlet A 精确匹配,那么就去调用 servletA,也不会去理会其他的 servlet。
最长路径匹配:
例子:servlet A 的 url-pattern 为 /test/*,而 servlet B 的 url-pattern 为 /test/a/*,此时访问 http://localhost/test/a 时,容器会选择路径最长的 servlet 来匹配,也就是这里的 servletB。
扩展匹配:如果 url 最后一段包含扩展,容器将会根据扩展选择合适的 servlet。
例子:servletA 的 url-pattern:*.action 等等
4.servlet,filter 都是针对 url 的,而 listener 是针对对象的操作的,如 session 的创建,session.setAttribute 的发生,在这样的事件发生时做一些事情。可用来进行 web 应用定时任务的实现,在线人数的统计等。
5.Spring 中的过滤器和拦截器的区别与联系:
(1)拦截器是 Spring 提供的,而过滤器是由 Servlet 标准提供的。
(2)拦截器在 Spring.xml 中配置,而过滤器在 web.xml 文件中配置。
(3)过滤器在配置文件中的位置决定了先后执行顺序。
(4)拦截器是基于反射机制的,而过滤器是基于函数回调。
(5)过滤器依赖 servlet 容器,而拦截器不依赖 servlet 容器。