目录
一.介绍
二.ServletContext对象的生命周期监听器
三.ServletContext对象的属性操作监听器
四.HttpSession对象的生命周期监听器
五.HttpSession对象的属性操作监听器
六.HttpServletRequest对象的生命周期监听器
七.HttpServletRequest对象的属性操作监听器
八.基于注解式开发监听器
九.Filter与Listener设计模式
一.介绍
监听器用于监听
web
应用中某些对象的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态
发生变化的时候,服务器会自动调用监听器对象中的方法。
监听器分类
按监听的对象划分,可以分为:
- ServletContext对象生命周期监听器与属性操作监听器;
- HttpSession对象生命周期监听器与属性操作监听器;
- ServletRequest对象生命周期监听器与属性操作监听器;
二.ServletContext对象的生命周期监听器
ServletContextListener
接口定义了
ServletContext
对象生命周期的
监听行为。
void contextInitialized(ServletContextEvent sce)
ServletContext
对象创建之后会触发该监听方法,并将ServletContext
对象传递到该方法中。
void contextDestroyed(ServletContextEvent sce)
ServletContext
对象在销毁之前会触发该监听方法,并将ServletContext
对象传递到该方法中。
?
在src下新建一个listener目录用于本篇文章的功能代码
ServletContextLifecyclelistener.java:
package com.first.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//ServletContext生命周期监听器
public class ServletContextLifecyclelistener implements ServletContextListener {
//Code-->Implement Methods 实现接口函数
//监听ServletContext对象创建的监听方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//初始化和销毁时都输出ServletContext对象地址,看看是否是同一个对象
ServletContext sc=sce.getServletContext();
System.out.println(sc);
System.out.println("ServletContext Init...");
}
//监听ServletContext对象销毁的监听方法
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContext sc=sce.getServletContext();
System.out.println(sc);
System.out.println("ServletContext Destroy...");
}
}
配置web.xml:
<listener>
<listener-class>com.first.listener.ServletContextLifecyclelistener</listener-class>
</listener>
输出:
启动时控制台输出 :
ServletContext Init...
注意销毁时不要直接在idea中点按钮关闭,而是去tomcat的安装目录下,点击bin目录下的shutdown.bat进行销毁。
销毁时控制台输出:
ServletContext Destroy...
且可看到控制台两次输出的对象地址都一样:
org.apache.catalina.core.ApplicationContextFacade@505077d9
三.ServletContext对象的属性操作监听器
ServletContextAttributeListener
接口定义了对于
ServletContext
对象属性操作的监听行为。
void attributeAdded(ServletContextAttributeEvent scae)
向
ServletContext
对象中添加属性时会触发该监听方法,并将
ServletContext
对象传递到该方法中。触发事件的方法
servletContext.setAttribute("key","value")
。
void attributeRemoved(ServletContextAttributeEvent scae)
当从
ServletContext
对象中删除属性时会触发该监听方法,并将ServletContext
对象传递到该方法中。
触发事件方法
servletContext.removeAttribute("key")
。
void attributeReplaced(ServletContextAttributeEvent scae)
当从
ServletContext
对象中属性的值发生替换时会触发该监听方法,并将
ServletContext
对象传递到该方法中。
触发事件的方法
servletContext.setAttribute("key","value")
。
ServletContextAttrListener.java:
package com.first.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
//ServletContext属性监听器
public class ServletContextAttrListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("-----------Start Added-------------");
//输出键值
System.out.println("Name:"+scae.getName()+" Value:"+scae.getValue());
System.out.println(scae.getServletContext());
System.out.println("------------End Added------------");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("-----------Start Removed-------------");
//输出键值
System.out.println("Name:"+scae.getName()+" Value:"+scae.getValue());
System.out.println(scae.getServletContext());
System.out.println("------------End Removed------------");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("-----------Start Replaced-------------");
//输出键值
System.out.println("Name:"+scae.getName()+" Value:"+scae.getValue());
System.out.println(scae.getServletContext());
System.out.println("------------End Replaced------------");
}
}
配置web.xml:
<listener>
<listener-class>com.first.listener.ServletContextAttrListener</listener-class>
</listener>
?ServletContextAttrServlet.java:
package com.first.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//ServletContext属性监听器测试(Servlet
@WebServlet("/attr.do")
public class ServletContextAttrServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
//触发attributeAdded
servletContext.setAttribute("key","sb");
//触发attributeReplaced
servletContext.setAttribute("key","brave");
//触发attributeRemoved
servletContext.removeAttribute("key");
}
}
?输出:
浏览器地址访问http://localhost:8888/ajaxDemo/attr.do
控制台输出:
-----------Start Added-------------
Name:key Value:sb
org.apache.catalina.core.ApplicationContextFacade@6014fd5a
------------End Added------------
-----------Start Replaced-------------
Name:key Value:sb
org.apache.catalina.core.ApplicationContextFacade@6014fd5a
------------End Replaced------------
-----------Start Removed-------------
Name:key Value:brave
org.apache.catalina.core.ApplicationContextFacade@6014fd5a
------------End Removed------------
四.HttpSession对象的生命周期监听器
HttpSessionListener
接口定义了
HttpSession
对象生命周期的监听行为。
void sessionCreated(HttpSessionEvent se)
HttpSession
对象创建后会触发该监听方法,并将已创建HttpSession
对象传递到该方法中。
void sessionDestroyed(HttpSessionEvent se)
HttpSession
对象在销毁之前会触发该监听方法,并将要销毁的HttpSession
对象传递到该方法中。
?
?HttpSessionLifecyclelistener.java:
package com.first.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class HttpSessionLifecyclelistener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("sessionCreated");
System.out.println(se.getSession());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("sessionDestroyed");
System.out.println(se.getSession());
}
}
配置web.xml:
<listener>
<listener-class>com.first.listener.HttpSessionLifecyclelistener</listener-class>
</listener>
输出:
自己启动试试吧,其中前面学的章节中(戳这里),销毁HttpSession对象时有两种方法,一是超时时间到了,二是调用了invalidate()方法。
五.HttpSession对象的属性操作监听器
HttpSessionAttributeListener
接口定义了对于
HttpSession
对象属性操作的监听行为。
void attributeAdded(HttpSessionBindingEvent se)
向
HttpSession
对象中添加属性时会触发该监听方法,并将HttpSession
对象传递到该方法中。
触发事件的方法
HttpSession.setAttribute("key","value")
。
void attributeRemoved(HttpSessionBindingEvent se)
当从
HttpSession
对象中删除属性时会触发该监听方法,并将HttpSession
对象传递到该方法中。
触发事件方法
HttpSession.removeAttribute("key")
。
void attributeReplaced(HttpSessionBindingEvent se)
当从
HttpSession
对象中属性的值发生替换时会触发该监听方法,并将
HttpSession
对象传递到该方法中。
触发事件的方法
HttpSession.setAttribute("key","value")
。
?
HttpSessionAttrListener.java:
package com.first.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class HttpSessionAttrListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("----------HttpSessionAttrListener----Start Added----------");
System.out.println("Name: "+se.getName()+" Value: "+se.getValue());
System.out.println(se.getSession());
System.out.println("----------HttpSessionAttrListener----End Added----------");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("----------HttpSessionAttrListener----Start Removed----------");
System.out.println("Name: "+se.getName()+" Value: "+se.getValue());
System.out.println(se.getSession());
System.out.println("----------HttpSessionAttrListener----End Removed----------");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("----------HttpSessionAttrListener----Start Replaced----------");
System.out.println("Name: "+se.getName()+" Value: "+se.getValue());
System.out.println(se.getSession());
System.out.println("----------HttpSessionAttrListener----End Replaced----------");
}
}
配置web.xml:
<listener>
<listener-class>com.first.listener.HttpSessionAttrListener</listener-class>
</listener>
HttpSessionAttrServlet.java:
package com.first.listener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/sessionAttr.do")
public class HttpSessionAttrServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取HttpSession对象
HttpSession session=req.getSession();
//触发attributeAdded
session.setAttribute("key","brave");
//触发attributeReplaced
session.setAttribute("key","timid");
//触发attributeRemoved
session.removeAttribute("key");
}
}
?输出:
访问http://localhost/ajaxDemo/sessionAttr.do
----------HttpSessionAttrListener----Start Added----------
Name: key Value: brave
org.apache.catalina.session.StandardSessionFacade@656b023d
----------HttpSessionAttrListener----End Added----------
----------HttpSessionAttrListener----Start Replaced----------
Name: key Value: brave
org.apache.catalina.session.StandardSessionFacade@656b023d
----------HttpSessionAttrListener----End Replaced----------
----------HttpSessionAttrListener----Start Removed----------
Name: key Value: timid
org.apache.catalina.session.StandardSessionFacade@656b023d
----------HttpSessionAttrListener----End Removed----------
六.HttpServletRequest对象的生命周期监听器
ServletRequestListener
接口定义了
ServletRequest(
是HttpServletRequest
接口的父接口类型
)
对象生命周期的监听行为。
?
void requestInitialized(ServletRequestEvent sre)
HttpServletRequest
对象创建后会触发该监听方法,并将已创建HttpServletRequest
对象传递到该方法中。
void requestDestroyed(ServletRequestEvent sre)
HttpServletRequest
对象在销毁之前会触发该监听方法,并将要销毁
HttpServletRequest
对象传递到该方法中。
当有请求时,tomcat会创建一个servlet,故而下面的代码会执行。
HttpServletRequestLifecycleListener.java
package com.first.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
/**
* 监听HttpServletRequest生命周期的监听器
*/
public class HttpServletRequestLifecycleListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("----------Start requestDestroyed------------");
System.out.println((HttpServletRequest)sre.getServletRequest());
System.out.println("----------End requestDestroyed------------");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("----------Start Initialized------------");
System.out.println((HttpServletRequest)sre.getServletRequest());
System.out.println("----------End Initialized------------");
}
}
web.xml:
<listener>
<listener-class>com.first.listener.HttpServletRequestLifecycleListener</listener-class>
</listener>
控制台输出:
----------Start requestDestroyed------------
org.apache.catalina.connector.RequestFacade@5f402c23
----------End requestDestroyed------------
----------Start Initialized------------
org.apache.catalina.connector.RequestFacade@5f402c23
----------End Initialized------------
七.HttpServletRequest对象的属性操作监听器
ServletRequestAttributeListener
接口定义了对于HttpServletRequest
对象属性操作的监听行为。
void attributeAdded(ServletRequestAttributeEvent srae)
向
HttpServletRequest
对象中添加属性时会触发该监听方法,并将HttpServletRequest
对象传递到该方法中。
触发事件的方法
HttpServletRequest.setAttribute("key","value")
。
void attributeRemoved(ServletRequestAttributeEvent srae)
当从
HttpServletRequest
对象中删除属性时会触发该监听方法,并将
HttpServletRequest
对象传递到该方法中。
触发事件方法
HttpServletRequest.removeAttribute("key")
。
?
void attributeReplaced(ServletRequestAttributeEvent srae)
当从
HttpServletRequest
对象中属性的值发生替换时会触发该监听方法,并将
HttpServletRequest
对象传递到该方法中。
触发事件的方法
HttpServletRequest.setAttribute("key","value")
。
HttpServletRequestAttrListener.java:
package com.first.listener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
/**
* HttpServletRequest对象属性监听器
*/
public class HttpServletRequestAttrListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("---HttpServletRequestAttrListener-----------Start Added-----------");
System.out.println("Name: "+srae.getName()+" Value: "+srae.getValue());
System.out.println(srae.getServletRequest());
System.out.println("---HttpServletRequestAttrListener-----------End Added-----------");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("---HttpServletRequestAttrListener-----------Start Removed-----------");
System.out.println("Name: "+srae.getName()+" Value: "+srae.getValue());
System.out.println(srae.getServletRequest());
System.out.println("---HttpServletRequestAttrListener-----------End Removed-----------");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println("---HttpServletRequestAttrListener-----------Start Replaced-----------");
System.out.println("Name: "+srae.getName()+" Value: "+srae.getValue());
System.out.println(srae.getServletRequest());
System.out.println("---HttpServletRequestAttrListener-----------End Replaced-----------");
}
}
?web.xml:
<listener>
<listener-class>com.first.listener.HttpServletRequestAttrListener</listener-class>
</listener>
?HttpServletRequestAttrServlet.java:
package com.first.listener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/requestAttr.do")
public class HttpServletRequestAttrServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("key","prospect");
req.setAttribute("key","entertainment");
req.removeAttribute("key");
}
}
输出:
访问:http://localhost:8888/ajaxDemo/requestAttr.do
输出看控制台。
八.基于注解式开发监听器
Listener
支持注解式开发,通过
@WebListener
注解替代
web.xml
中Listener
的配置。
以本文章第一个例子为例:
把web.xml里的相应配置去了,然后顶部添加@WebListener即可,无需配置参数!
?
九.Filter与Listener设计模式
“
知其然,知其所以然
”
。
Filter
的设计模式
在
Servlet
的
Filter
中使用的责任链设计模式。
责任链模式特点
责任链(
Chain of Responsibility
):责任链模式也叫职责链模式,是一种对象行为模式。在责任链模式里,很多对象由每一个对象对
其下一个对象的引用而连接起来形成一条链。请求在这个链上传
递,直到链上的某一个对象决定处理此请求。发出这个请求的客户
端并不需要知道链上的哪一个对象最终处理这个请求,这使得系统
可以在不影响客户端的情况下动态地重新组织链和分配责任。
责任链的优缺点
优点:
- 降低了对象之间的耦合度。
- 增强了系统的可扩展性。
- 增强了给对象指派职责的灵活性。
- 责任链简化了对象之间的连接。
- 责任分担。每个类只需要处理自己该处理的工作。
缺点:
- 不能保证请求一定被接收。
- 对比较长的责任链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
- 可能会由于责任链的错误设置而导致系统出错,如可能会造成循环调用。
Listener
的设计模式
在
Servlet
的
Listener
中使用的观察者设计模式。
观察者模式的特点
观察者模式(
Observer Pattern
):观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发
生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式的优缺点
优点:
- 观察者和被观察者是抽象耦合的。
- 建立一套触发机制。
缺点:
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
?
|