Servlet监听

在《Servlet和Jsp》中我们使用了ServletConfig获取Servlet的初始配置,用ServletContext来获取整个Web应用的初始配置,但如果需要在所有的Servlet之前初始化资源怎么办呢?比如DataSource、Log4j等,可惜Servlet没有main方法,它是靠Web容器(如Tomcat)来加载的。

幸运的是Servlet提供了一个类javax.servlet.ServletContextListener,它能够监听ServletContext一生中的两个关键事件:初始化(创建)和撤销。

小示例

新建net.oseye.web.listener.MyTestContextListener类实现javax.servlet.ServletContextListener:

public class MyTestContextListener implements ServletContextListener {

	public void contextInitialized(ServletContextEvent arg0) {
//通过ServletContext传递资源
arg0.getServletContext().setAttribute("name", "kevin");
} public void contextDestroyed(ServletContextEvent arg0) {
// 不需要销毁资源
}
}

在DD文件中配置Context监听:

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<display-name>Archetype Created Web Application</display-name> <listener>
<listener-class>net.oseye.web.listener.MyTestContextListener</listener-class>
</listener> <servlet>
<servlet-name>HelloOther</servlet-name>
<display-name>HelloOther</display-name>
<description></description>
<servlet-class>net.oseye.web.HelloOther</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>HelloOther</servlet-name>
<url-pattern>/HelloOther</url-pattern>
</servlet-mapping> </web-app>

在Servlet中获取Context值并使用:

String name=(String) getServletContext().getAttribute("name");
response.getWriter().println("name:"+name);

Servlet中使用Log4J

Log4j的配置文件在项目中的位置如下图:

log4j.properties内容

log4j.logger.net.oseye=INFO,WebFile

log4j.appender.WebFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.WebFile.File=d:/log/testweb/web.log
log4j.appender.WebFile.DatePattern=yyyy-MM-dd-HH'.log'
log4j.appender.WebFile.layout=org.apache.log4j.PatternLayout
log4j.appender.WebFile.layout.ConversionPattern=%d{HH:mm:ss,SSS} %M %m%n

在pom.xml中添加slf4j依赖

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>

web.xml配置监听

<listener>
<listener-class>
net.oseye.web.listener.MyTestContextListener
</listener-class>
</listener>

net.oseye.web.listener.MyTestContextListener监听类代码

public class MyTestContextListener implements ServletContextListener {

	public void contextInitialized(ServletContextEvent arg0) {
//通过ServletContext传递资源
arg0.getServletContext().setAttribute("name", "kevin");
PropertyConfigurator.configure(arg0.getServletContext().getRealPath("/config/log4j.properties"));
} public void contextDestroyed(ServletContextEvent arg0) {
// 不需要销毁资源
}
}

在Servlet中记录日志

Logger logger=LoggerFactory.getLogger(HelloOther.class);
logger.info("测试Log4j");

监听器

只要是在生命周期里的重要时刻,总会有一个监听器在监听,下面是8个监听器

场景 监听器接口 时间类型
你想知道一个web应用上下文中是否增加、删除或替换了一个属性

javax.servlet.ServletContextAttributeListener
attributeAdded
attributeRemoved
attributeReplaced

ServletContextAttributeEvent
你想知道有多少个并发用户,也就是说,你想跟踪活动的会话

javax.servlet.http.HttpSessionListener
sessionCreated
sessionDestroyed

HttpSessionEvent
每次请求到来时你都想知道,以便建立日志记录

javax.servlet.ServletRequestListener
requestInitialized
requestDestroyed

ServletRequestEvent
增加、删除或替换一个请求属性时你希望能够知道

javax.servlet.ServletRequestAttributeListener
attributeAdded
attributeRemoved
attributeReplaced

ServletRequestAttributeListener
你有一个属性类,而且你希望这个类型的对象在绑定到一个会话或从会话中或从会话删除时得到通知

javax.servlet.HttpSessoinBindingListener
valueBound
valueUnbound

HttpSessionBindingEvent
增加、删除或添加一个会话属性时你希望能够知道

javax.servlet.HttpSessionAttributeListener
attributeAdded
attributeRemoved
attributeReplaced

HttpSessionBindingEvent
你想知道是否创建或撤销了一个上下文

javax.servlet.ServletContextListener
contextInitializated
contextDestroyed

ServletContextEvent
你有一个属性类,而且希望这个类型的对象在其绑定的会话迁移到另一个JVM时得到通知

javax.servlet.http.HttpSessionActivationListener
sessionDidActivite
sessionWillPassivate

HttpSessionEvent

HttpSessionListener和HttpSessionActivationListener共用HttpSessionEvent事件;ServletSessionBindingListener和ServletSessionAttributeListener共用HttpSessionBindingEvent事件。
如在部署描述文件web.xml添加监听

<listener>
<listener-class>net.oseye.web.listener.ContextAttributeListener</listener-class>
</listener>
<listener>
<listener-class>net.oseye.web.listener.SessionLinstener</listener-class>
</listener>

net.oseye.web.listener.ContextAttributeListener

public class ContextAttributeListener implements ServletContextAttributeListener {
private static Logger logger=LoggerFactory.getLogger(ContextAttributeListener.class); public void attributeAdded(ServletContextAttributeEvent arg0) {
logger.info("name:{} val:{}",arg0.getName(),arg0.getValue().toString()); } public void attributeRemoved(ServletContextAttributeEvent arg0) {
// TODO Auto-generated method stub } public void attributeReplaced(ServletContextAttributeEvent arg0) {
// TODO Auto-generated method stub }
}

net.oseye.web.listener.SessionLinstener

public class SessionLinstener implements HttpSessionListener {
private static Logger log=LoggerFactory.getLogger(SessionLinstener.class); public void sessionCreated(HttpSessionEvent arg0) {
log.info("创建-"+arg0.getSession().getId());
} public void sessionDestroyed(HttpSessionEvent arg0) {
log.info("销毁-"+arg0.getSession().getId());
}
}

对于ServletContextAttributeListener我的测试只能监听ServletContext()操作的属性,而对于在DD文件中的却没能监听到,如web.xml配置:

<context-param>
<param-name>email</param-name>
<param-value>kevin@oseye.net</param-value>
</context-param>

PS:这里是我理解错误,把属性和上下文参数搞混了,在web.xml中配置的是上下文参数。


Context属性和会话属性的多线程

Context属性和会话属性因为作用域很大,所以他们不是线程安全的,我们一般这样保证线程安全

synchronized (getServletContext()) {
getServletContext().setAttribute("name", "kevin");
getServletContext().setAttribute("age", "22");
} synchronized (request.getSession()) {
request.getSession().setAttribute("name", "kevin");
request.getSession().setAttribute("age", "22");
}

PS:每个Servlet只有一个实例对象(Instance),但可以被多个线程访问;这里强调这点并不是为了解释上面的属性线程不安全,因为即使是多个实例对象,也会有多个Servlet造成属性线程不安全的。

Servlet的监听的更多相关文章

  1. jsp&servlet——session监听

    session监听,需要实现HttpSessionAttributeListener接口 attributeAdded:监听添加session attributeRemoved:监听删除session ...

  2. java web hello world(二)基于Servlet理解监听

    java web最开始实现是通过Servlet实现,这里就来实现下,最原始的监听是如何实现的. 第一步,创建一个基本的web项目 ,参见(java web hello world(一)) 第二步,we ...

  3. Servlet之监听事件细究

    观察者三个模式: ServletContextListener:用于监听WEB 应用启动和销毁的事件,监听器类需要实现javax.servlet.ServletContextListener 接口. ...

  4. javaweb监听

    监听项目启动 package com.java7115.quartz; import javax.servlet.ServletContextEvent; import javax.servlet.S ...

  5. JavaWeb监听器的使用(一)监听上下文和会话信息

    1.监听上下文的类 package com.examp.ch9; import java.io.FileOutputStream; import java.io.PrintWriter; import ...

  6. tomcat触发ServletContext初始化监听事件的源码(原创)

    tomcat 8.0.36 知识点: 动态监听器的好处可以根据环境条件进行选择性添加. 静态监听器有七类. ServletContextAttributeListener ServletRequest ...

  7. 【Java EE 学习 21 上】【其它类型的监听器】【使用HttpSessionActivationListener监听session的活化和钝化】

    一.ServletContextListener  Method Summary  void contextDestroyed(ServletContextEvent sce)           R ...

  8. 解决tomcat启动Socket监听端口死循环被hold问题

    原文链接:http://blog.csdn.net/dead_cicle/article/details/7073433 1.SOCKET监听置于servlet的init方法中,在web.xml里加入 ...

  9. java web session监听销毁跳转

    1.了解如何使用HttpSessionListener监听session的销毁. 2.了解如何使用HttpSessionBindingListener监听session的销毁. 一. 使用HttpSe ...

随机推荐

  1. 兼容ie6及以上和firefox等标准浏览器的表格行滑过时背景色切换的效果

    一.js代码——"tablehover.js" /**      *②.表格单元行滑过时高亮样式动效组件封装      *oop形式封装交互动效类      *组件说明这个组件是为 ...

  2. AFNetWorking 之 Get/Post 请求的使用

    1. Get 与 Post 比较 GET请求:简单业务.明文发送 POST请求:上传文件,重要信息.加密信息,.大数据信息. 2. 序列化 默认是JSon格式. // 请求的序列化 manager.r ...

  3. js原生设计模式——9外观模式封装

    1.事件处理程序兼容性封装 <!DOCTYPE html><html lang="en"><head>    <meta charset= ...

  4. js原生之函数

    1.函数作为参数传给其他函数:    data.sort(function(a,b){return a-b})    //关于数组的sort函数,其回调函数返回负值,a在b之前    //正值,b在a ...

  5. 关于自己封装Web前端框架的思考和探索

    一.引言 首先这些年关于前端技术层出不穷,从最早的只用js做简单验证,到现在发现好像大前端已经无所不能了的感觉.特别是为了降低前端开发复杂度,涌现了一大批 的MVC/MVVM模式的前端框架,不停了刷新 ...

  6. 用SWF来代替传统的帧动画

    一般的帧动画是有两大缺点: 1.资源浪费,包大 2.很难实现平滑过渡 特别对于GIF,还会存在噪点问题,但是SWF利用自身的优势,不仅有现成的编辑器,而且还有矢量动画,补间动画等,大大 降低了资源的大 ...

  7. 从svn上回滚版本

    转载地址:http://blog.csdn.net/happyqyt/article/details/7107039 提交SVN后想回滚到旧版本. 选择TortoiseSVN→Repo-browser ...

  8. ArcGIS API for JavaScript 4.2学习笔记[2] 显示3D地图

    3D地图又叫场景. 由上一篇可知, require入口函数的第一个参数是字符串数组 ["esri/Map", "esri/views/MapView", &qu ...

  9. 详谈Struts2

    介绍struts2: struts2是一个基于mvc设计模式的web层框架. 详谈struts2的执行流程: struts2的执行流程:用户发送请求---->首先经过Struts2的核心过滤器- ...

  10. (译)AngularJS1.3.0 开发者指南(四) -- 控制器

    理解Controllers 在AngularJS中, Controller是一个Javascript构造函数, 常常被用来扩展 Angular Scope 对象. 控制器通过 ng-controlle ...