1.监听器作用
监听器Listener就是在application、session、request三个对象创建、销毁或者往其中添加、修改、删除属性时自动执行的功能组件。
2.监听器分类
(1)ServletContext监听
1) ServletContextListener
用于监听ServletContext的创建和销毁
public interface ServletContextListener extends EventListener
{
//ServletContext创建时候会调用该方法
public void contextInitialized ( ServletContextEvent sce );
//ServletContext销毁时会调用
public void contextDestroyed ( ServletContextEvent sce );
}
其中的事件:ServletContextEvent
public class ServletContextEvent extends java.util.EventObject
{
public ServletContextEvent(ServletContext source)
{
super(source);
}
//获得ServletContext对象
public ServletContext getServletContext ()
{
return (ServletContext) super.getSource();
}
}
2) ServletContextAttributeListener
用于监听ServletContext中属性的增加、删除、修改
public interface ServletContextAttributeListener extends EventListener
{
/**当一个属性被添加的时候调用.在添加之后被调用.*/
public void attributeAdded(ServletContextAttributeEvent scab);
/** 当一个属性被删除的时候调用.在删除之后被调用.*/
public void attributeRemoved(ServletContextAttributeEvent scab);
/** 当一个属性被替换(也就是第二次替换原来的值)的时候调用.在替换之后被调用 */
public void attributeReplaced(ServletContextAttributeEvent scab);
}
其中的事件ServletContextAttributeEvent
public class ServletContextAttributeEvent extends ServletContextEvent
{
private String name;
private Object value;
public ServletContextAttributeEvent(ServletContext source, String name, Object value)
{
super(source);
this.name = name;
this.value = value;
}
//获得触发事件的属性名臣
public String getName()
{
return this.name;
}
//获得触发事件的属性的值
public Object getValue()
{
return this.value;
}
}
(2)Session监听
1) HttpSessionListener
对session的创建和销毁监听public interface HttpSessionListener extends EventListener
{
//创建Session时调用
public void sessionCreated ( HttpSessionEvent se );
//销毁Session时调用
public void sessionDestroyed ( HttpSessionEvent se );
}
其中的事件HttpSessionEvent
public class HttpSessionEvent extends java.util.EventObject
{
/** Construct a session event from the given source.*/
public HttpSessionEvent(HttpSession source)
{
super(source);
}
/** 返回触发事件的Session*/
public HttpSession getSession ()
{
return (HttpSession) super.getSource();
}
}
2) HttpSessionAttributeListener
对session中属性的添加、删除、替换监听public interface HttpSessionAttributeListener extends EventListener
{
/** Notification that an attribute has been added to a session. Called after the attribute is added.*/
public void attributeAdded ( HttpSessionBindingEvent se );
/** Notification that an attribute has been removed from a session. Called after the attribute is removed. */
public void attributeRemoved ( HttpSessionBindingEvent se );
/** Notification that an attribute has been replaced in a session. Called after the attribute is replaced. */
public void attributeReplaced ( HttpSessionBindingEvent se );
}
其中的事件HttpSessionBingdingEvent
public class HttpSessionBindingEvent extends HttpSessionEvent
{
private String name;
private Object value;
/** Return the session that changed. */
public HttpSession getSession ()
{
return super.getSession();
}
public String getName()
{
return name;
}
public Object getValue()
{
return this.value;
}
}
注意:
Session的销毁有2种情况:
I.session超时,这个在web.xml中可以配置
<session-config>
<session-timeout>120</session-timeout><!--session120分钟后超时销毁-->
</session-config>
II.手工使session失效
public void invalidate();//使session失效方法。session.invalidate();
(3)request监听
1)ServletRequestListener
对request的创建和销毁监听public interface ServletRequestListener extends EventListener
{
/** The request is about to go out of scope of the web application. */
public void requestDestroyed ( ServletRequestEvent sre );
/** The request is about to come into scope of the web application. */
public void requestInitialized ( ServletRequestEvent sre );
}
其中的事件ServletRequestEvent
public class ServletRequestEvent extends java.util.EventObject
{
private ServletRequest request;
public ServletRequestEvent(ServletContext sc, ServletRequest request)
{
super(sc);
this.request = request;
}
//返回事件相关的Request
public ServletRequest getServletRequest ()
{
return this.request;
}
//返回事件相关的ServletContext
public ServletContext getServletContext () {
return (ServletContext) super.getSource();
}
}
2)ServletRequestAttributeListener
对request中属性的添加、删除、替换监听public interface ServletRequestAttributeListener extends EventListener
{
/** Notification that a new attribute was added to the
** servlet request. Called after the attribute is added.
*/
public void attributeAdded(ServletRequestAttributeEvent srae);
/** Notification that an existing attribute has been removed from the
** servlet request. Called after the attribute is removed.
*/
public void attributeRemoved(ServletRequestAttributeEvent srae);
/** Notification that an attribute was replaced on the
** servlet request. Called after the attribute is replaced.
*/
public void attributeReplaced(ServletRequestAttributeEvent srae);
}
其中触发的事件ServletRequestAttributeEvent
public class ServletRequestAttributeEvent extends ServletRequestEvent {
private String name;
private Object value;
public ServletRequestAttributeEvent(ServletContext sc, ServletRequest request, String name, Object value) {
super(sc, request);
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public Object getValue() {
return this.value;
}
}
3.监听器使用
(1)创建监听器类,实现上面的一个或者多个接口
(2)在web.xml中配置
<listener>
<listener-class>com.listener.class</listener-class>
</listener>
注意:
Listener的配置信息必须写在Filter和Servlet之前,因为初始化顺序为Listener->Filter->Servlet
4.应用
(1)使用监听器记录在线人数
public class MaxUserCountListener implements HttpSessionListener {
public MaxUserCountListener()
{
}
public void sessionCreated(HttpSessionEvent se)
{
System.out.println("enter");
ServletContext sc = se.getSession().getServletContext();
Object count = sc.getAttribute("count");
if(count==null)
{
sc.setAttribute("count", 1);
}
else
{
int newCount = Integer.valueOf(count.toString());
newCount++;
sc.setAttribute("count", newCount);
}
}
//session注销、超时时候调用,停止tomcat不会调用
public void sessionDestroyed(HttpSessionEvent se)
{
ServletContext sc = se.getSession().getServletContext();
int count = Integer.valueOf(sc.getAttribute("count").toString());
count--;
sc.setAttribute("count", count);
}
}
(2)Spring使用ContextLoaderListener加载ApplicationContext配置信息
ContextLoaderListener的作用就是在启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,容器启动时,就会默认执行他的实现方法。
ContextLoaderListener如何查找ApplicationContext.xml的配置位置以及配置多个xml文件:如果web.xml中没有写任何参数配置信息,默认路径是“/WEB-INF/applicationContext.xml”,在WEB-INF目录下创建的xml文件名称必须是applicationContext.xml。如果需要自定义文件名,可以在web.xml中加入contextConfigLocation这个context参数
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value><!-- 采用的是通配符方式,查找WEB-INF/spring目录下xml文件。如有多个xml文件,以“,”分隔。 -->
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
(3)Spring使用Log4jConfigListener配置Log4j日志
Spring使用Log4jConfigListener的好处:
1)动态的改变记录级别和策略,不需要重启Web应用
2)把log文件定在/WEB-INF/logs/而不需要写绝对路径。因为系统把web目录的路径压入webapp.root的系统变量。
3)可以把log4j.properties和其他properties一起放在/WEB-INF
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>project.root</param-value><!-- 用于定位log文件输出位置在web应用根目录下,log4j配置文件中写输出位置:log4j.appender.FILE.File=${project.root}/logs/project.log -->
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value><!-- 载入log4j配置文件 -->
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value><!--Spring刷新Log4j配置文件的间隔60秒,单位为millisecond-->
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>