【转载并整理】filter、servlet、interceptor、listener区别
参考文章:https://blog.csdn.net/u013087513/article/details/56835894
一、servlet
servlet是一种运行服务器端的java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层。最早支持 Servlet 技术的是 JavaSoft 的 Java Web Server。此后,一些其它的基于 Java 的 Web Server 开始支持标准的 Servlet API。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。这个过程为:
1) 客户端发送请求至服务器端;
2) 服务器将请求信息发送至 Servlet;
3) Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;
4) 服务器将响应返回给客户端。
Servlet的创建:Servlet可以在第一次接收请求时被创建,也可以在在服务器启动时就被创建,这需要在web.xml的< servlet>中添加一条配置信息 < load-on-startup>5< /load-on-startup>,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet,当是一个负数时或者没有指定时,则指示容器在该servlet被请求时才加载。
Servlet的生命周期方法:
> void init(ServletConfig)
servlet的初始化方法,只在创建servlet实例时候调用一次,Servlet是单例的,整个服务器就只创建一个同类型Servlet
> void service(ServletRequest,ServletResponse)
servlet的处理请求方法,在servle被请求时,会被马上调用,每处理一次请求,就会被调用一次。ServletRequest类为请求类,ServletResponse类为响应类
> void destory()
servlet销毁之前执行的方法,只执行一次,用于释放servlet占有的资源,通常Servlet是没什么可要释放的,所以该方法一般都是空的
Servlet的其他重要方法:
> ServletConfig getServletConfig()
获取servlet的配置信息的方法,所谓的配置信息就是WEB-INF目录下的web.xml中的servlet标签里面的信息
> String getServletInfo()
获取servlet的信息方法
Servlet的配置:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.briup.estore.web.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
二. filter
filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。
其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。
Filter有如下几个用处。
在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
Filter有如下几个种类。
用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
日志Filter:详细记录某些特殊的用户请求。
负责解码的Filter:包括对非标准编码的请求解码。
能改变XML内容的XSLT Filter等。
Filter可负责拦截多个请求或响应;一个请求或响应也可被多个请求拦截。
Filter链——FilterChain
Filter生命周期
- 和我们编写的Servlet程序一样,Filter的创建与销毁由WEB服务器负责。web应用程序启动时,web服务器将创建Filter的实例对象,并调用init方法进行初始化(注意:filter对象只会创建一次,init方法也只会执行一次)
- 开发人员通过init方法的参数,可以获得代表当前filter配置信息的FilterConfig对象。
- 每次filter进行拦截都会执行
- 在实际开发中方法中参数request和response通常转换为HttpServletRequest和HttpServletResponse类型进行操作。
- 在web容器卸载Filter对象之前被调用
FilterConfig接
用户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的FilterConfig对象传递进来,因此开发人员在编写Filter时,通过FilterConfig对象的方法就可获得过滤器的初始化参数有关的信息以及获取ServletContext对象等信息:
- String getFilterName():得到filter的名称。
- String getInitParameter(String name):返回在部署描述中指定名称的初始化参数的值。如果不存在则返回null。
- Enumeration getInitParameterNames():返回过滤器中的所有初始化参数的名字的枚举集合。
- public ServletContext getServletContext():返回Servlet上下文对象的引用。
注册与映射Filter
(1)注册Filter
<filter>
<filter-name>testFitler</filter-name>
<filter-class>org.test.TestFiter</filter-class>
<init-param>
<param-name>word_file</param-name>
<param-value>/WEB-INF/word.txt</param-value>
</init-param>
</filter>
<filter-name> 用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class> 元素用于指定过滤器的完整的限定类名。
<init-param> 元素用于用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名称,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
(2)映射Filter
<filter-mapping> 元素用于设置一个Filter所负责拦截的资源。一个Filter拦截的资源可以通过两种方式来指定:Servlet名称和资源访问的请求路径。
<filter-name> 子元素用于设置Filter的注册名称。该值必须是在<filter>元素中生命过的过滤器的名称。
<url-pattern> 设置filter所拦截的请求路径(过滤器关联的URL样式)。
<servlet-name>指定过滤器所拦截的Servlet名称。
<dispatcher> 指定过滤器所拦截的资源被Servlet容器调用的方式,可以是REQUEST,INCLUDE,FORWARD,和ERROR之一,默认是REQUEST。用户可以设置多个<dispatcher>子元素用来指定Filter对资源的多种调用方式进行拦截。
注意:<url-pattern>有三种匹配方式和Servlet的配置方式类似
- 绝对路径匹配:以/开头 不包含通配符 * 是一个绝对访问路径。例如:/demo、/index.jsp
- 目录匹配:以/ 开头,以 * 结尾。例如:/*、/servlet/*、/servlet/xxx/*
- 扩展名匹配:不能以/ 开头,也不能以*结尾 只能以后缀名结尾 例如:*.do、*.demo等
映射Filter的多种方式:
- REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
- INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
- ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
三. Listener
Listener就是监听器,我们在JavaSE开发或者Android开发时,经常会给按钮加监听器,当点击这个按钮就会触发监听事件,调用onClick方法,本质是方法回调。在JavaWeb的 Listener也是这么个原理,但是它监听的内容不同,它可以监听Application、Session、Request对象,当这些对象发生变化就会调用对应的监听方法。
应用域监听:
Ø ServletContext(监听Application)
生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
void contextInitialized(ServletContextEvent sce):创建Servletcontext时 void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时
属性监听:ServletContextAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
void attributeAdded(ServletContextAttributeEvent event):添加属性时; void attributeReplaced(ServletContextAttributeEvent event):替换属性时; void attributeRemoved(ServletContextAttributeEvent event):移除属性时;
Ø HttpSession(监听Session)
生命周期监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
voidsessionCreated(HttpSessionEvent se):创建session时 void sessionDestroyed(HttpSessionEvent se):销毁session时
属性监听:HttpSessioniAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
void attributeAdded(HttpSessionBindingEvent event):添加属性时; void attributeReplaced(HttpSessionBindingEvent event):替换属性时 void attributeRemoved(HttpSessionBindingEvent event):移除属性时
Ø ServletRequest(监听Request)
生命周期监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在死亡时调用;
voidrequestInitialized(ServletRequestEvent sre):创建request时 void requestDestroyed(ServletRequestEvent sre):销毁request时
属性监听:ServletRequestAttributeListener,它有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。
voidattributeAdded(ServletRequestAttributeEvent srae):添加属性时 void attributeReplaced(ServletRequestAttributeEvent srae):替换属性时 void attributeRemoved(ServletRequestAttributeEvent srae):移除属性时
感知Session监听:
1:HttpSessionBindingListener监听
⑴在需要监听的实体类实现HttpSessionBindingListener接口
⑵重写valueBound()方法,这方法是在当该实体类被放到Session中时,触发该方法
⑶重写valueUnbound()方法,这方法是在当该实体类从Session中被移除时,触发该方法
2:HttpSessionActivationListener监听
⑴在需要监听的实体类实现HttpSessionActivationListener接口
⑵重写sessionWillPassivate()方法,这方法是在当该实体类被序列化时,触发该方法
⑶重写sessionDidActivate()方法,这方法是在当该实体类被反序列化时,触发该方法
四. 拦截器Interceptor
Java里的拦截器提供的是非系统级别的拦截,也就是说,就覆盖面来说,拦截器不如过滤器强大,但是更有针对性。
Java中的拦截器是基于Java反射机制实现的,更准确的划分,基于JDK实现的动态代理。它依赖于具体的接口,在运行期间动态生成字节码。
拦截器是AOP的一个实现
参考一篇关于springmvc的拦截器说明:https://blog.csdn.net/xnf1991/article/details/53113519