Servlet3.0中的监听器跟之前2.5的差别不大,唯一的区别就是增加了对注解的支持。在3.0以前我们的监听器配置都是需要配置在web.xml文件中的。在3.0中我们有了更多的选择,之前在web.xml文件中配置的方式还是可以的,同时我们还可以使用注解进行配置。对于使用注解的监听器就是在监听器类上使用@WebListener进行标注,这样Web容器就会把它当做一个监听器进行注册和使用了。
监听器类应该实现下面接口之一:
1.对Request的监听有ServletRequestListener和ServletRequestAttributeListener。前者可见监听Request的创建和销毁;而后者可以对Request的属性进行监听。
2.对Session的监听有HttpSessionListener和HttpSessionAttributeListener。HttpSessionListener可以监听HttpSession的创建跟销毁,而HttpSessionAttributeListener则是对session中属性的监听,它可以监听到session新增属性、移除属性和属性值被替换时。
3.对于ServletContext的监听器有ServletContextListener和ServletContextAttributeListener。ServletContextListener可以监听到ServletContext的创建和销毁,而ServletContextAttributeListener可以监听到ServletContext中属性的新增、移除和属性值的替换。
实例1:
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
*
* HttpSession监听器和HttpSession属性监听器
*
*/
@WebListener
public class SessionListener implements HttpSessionAttributeListener,
HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session created");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session destroyed");
}
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("session attribute added");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println("session attribute removed");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println("session attribute replaced");
}
}
实例2:
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
*
* ServletContext监听器和ServletContext属性监听器
*
*/
@WebListener
public class ContextListener implements ServletContextAttributeListener,
ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext destroyed");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext initialized");
}
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println("ServletContext attribute added");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println("ServletContext attribute removed");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println("ServletContext attribute replaced");
}
}
为了文章的完整性,下面将给出上面监听器对应的在web.xml中配置的方式。
com.xxx.SessionListener
com.xxx.ContextListener
知识扩展:ServletContextListener
在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。
当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理ServletContextEvent 事件的两个方法。
/**
* 当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,
* 并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
*/
contextInitialized(ServletContextEvent sce)
/**
* 当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器。
*/
contextDestroyed(ServletContextEvent sce)
下面通过两个具体的例子来介绍 ServletContextListener 的用法。
例一:在服务启动时,将数据库中的数据加载进内存,并将其赋值给一个属性名,其它的 Servlet 就可以通过 getAttribute 进行属性值的访问。
有如下两个步骤:
1、ServletContext 对象是一个为整个 web 应用提供共享的内存,任何请求都可以访问里面的内容
2、如何实现在服务启动的时候就动态的加入到里面的内容:我们需要做的有:
1 ) 实现 servletContextListerner 接口 并将要共享的通过 setAttribute ( name,data )方法提交到内存中去 ;
2 )应用项目通过 getAttribute(name) 将数据取到 。
public class ServletContextLTest implements ServletContextListener{
// 实现其中的销毁函数
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("this is last destroyeed");
}
// 实现其中的初始化函数,当有事件发生时即触发
public void contextInitialized(ServletContextEvent sce) {
ServletContext sct=sce.getServletContext();
Map depts=new HashMap();
Connection connection=null;
PreparedStatement pstm=null;
ResultSet rs=null;
try{
connection=ConnectTool.getConnection();
String sql="select deptNo,dname from dept";
pstm=connection.prepareStatement(sql);
rs=pstm.executeQuery();
while(rs.next()){
depts.put(rs.getInt(1), rs.getString(2));
}
// 将所取到的值存放到一个属性键值对中
sct.setAttribute("dept", depts);
System.out.println("======listener test is beginning=========");
}catch(Exception e){
e.printStackTrace();
}finally{
ConnectTool.releasersc(rs, pstm, connection);
}
}
}
在完成上述编码后,仍需在 web.xml 中进行如下配置,以使得该监听器可以起作用。注意我们使用注解了,所以不需要这一步了。
1
2
3 ServletContextTest.ServletContextLTest
4
5
在完成上述配置后, web 服务器在启动时,会直接加载该监听器,通过以下的应用程序就可以进行数据的访问。
public class CreateEmployee extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sct=getServletConfig().getServletContext();
// 从上下文环境中通过属性名获取属性值
Map dept=(Map)sct.getAttribute("dept");
Set key=dept.keySet();
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("");
out.println("");
out.println("");
out.println("");
out.println("");
out.flush();
}
}