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. GWAS

    GWAS的数据形式:SNP数据,即各个SNP位点的aa,Aa,AA基因型与疾病状态(0正常,1患病)的样例-对照数据. 在遗传流行病学上,全基因组关联研究(Genome Wide Associatio ...

  2. win10新特性,ubuntu子系统(安装及配置)

    最新版win10下可以直接跑ubuntu镜像,直接入正题. 这里如果你没有可能是你的版本不是最新的,我这里是最新的win10直接是有这个功能的.勾选后会要求重启,确定即可. 然后win键弹出搜索,输入 ...

  3. Sql Server 查询多行并一行

    干货 CREATE TABLE #benefit_code21 (id INT, number nvarchar(MAX), pname ), collegeID INT, applicationda ...

  4. js控制公共模板中,不同页面中的导航选中效果-判断当前的url

    用js的做法也很多.比较推荐的方法是判断当前的url,然后根据url在nav中的位置,来对nav中的某个导航增加选中样式,代码如下: <!doctype html> <html la ...

  5. Bootstrap入门(八)组件2:下拉菜单

    Bootstrap入门(八)组件2:下拉菜单   先引入本地的CSS文件和JS文件(注:1.bootstrap是需要jQuery支持的.2.需要在<body>当中添加) <link ...

  6. HDU5505

    GT and numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  7. 从新手到高手c++全方位学习 pdf + 视频教程 共18章

    淘宝已经和谐了这个网站,原网址:https://item.taobao.com/item.htm?spm=a1z09.8149145.0.0.mb00D0&id=17350311256& ...

  8. BZOJ-2150部落战争(最小路径覆盖)

    2150: 部落战争 Time Limit: 10 Sec  Memory Limit: 259 MB Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国 ...

  9. ABP入门系列(10)——扩展AbpSession

    ABP入门系列目录--学习Abp框架之实操演练 源码路径:Github-LearningMpaAbp 一.AbpSession是Session吗? 1.首先来看看它们分别对应的类型是什么? 查看源码发 ...

  10. 【canvas系列】用canvas实现一个colorpicker

    每个浏览器都有自己的特点,比如今天要做的colorpicker就是,一千个浏览器,一千个哈姆雷特,一千个colorpicker.今天canvas系列就用canvas做一个colorpicker. ** ...