Java对Servlet中的ServletContext(上下文),HttpSession,ServletRequest这三种对象提供了一些监听的接口,我们可以自定义监听器来实现这些接口,对这三种对象的一些事件进行监听。

本文要实现的监听器接口列表

一,对ServletContext的监听 ServletContextListener:Servlet上下文初始化和销毁时的监听器。 ServletContextAttributeListener:Servlet上下文参数变化时的监听器。 二,对HttpSession的监听 HttpSessionListener:HttpSession初始化和销毁时的监听器。 HttpSessionAttributeListener:HttpSession参数变化时的监听器。 三,对ServletRequest的监听 ServletRequestListener:ServletRequest初始化和销毁时的监听器。 ServletRequestAttributeListener:ServletRequest参数变化时的监听器。

对于这三种对象的监听器不止这些,每种监听器分别监听了这些对象发生的不同的事件。

自定义的监听器实例

1,ServletContextListener

代码:

  1. package com.web.system.listener;
  2. import java.util.ArrayList;
  3. import javax.servlet.ServletContextEvent;
  4. import javax.servlet.ServletContextListener;
  5. /**
  6. * 自定义的ServletContext监听器,可以在ServletContext加载时做一些初始化的工作
  7. */
  8. public class MyServletContextListener implements ServletContextListener {
  9. @Override
  10. public void contextDestroyed(ServletContextEvent arg0) {
  11. System.out.println("MyServletContextListener Destoryed");
  12. }
  13. /**
  14. * servletContext初始化
  15. */
  16. @Override
  17. public void contextInitialized(ServletContextEvent arg0) {
  18. System.out.println("MyServletContextListener Init");
  19. ArrayList<String> expressList=new ArrayList<String>();
  20. expressList.add("顺丰速递");
  21. expressList.add("如风达");
  22. expressList.add("宅急送");
  23. expressList.add("EMS");
  24. arg0.getServletContext().setAttribute("expressList", expressList);
  25. }
  26. }

在web.xml中的配置:

  1. <listener>
  2. <listener-class>com.web.system.listener.MyServletContextListener</listener-class>
  3. </listener>

contextInitialized()方法就是在上下文加载时,监听器触发的方法,在这个方法中可以进行一些自定义的参数初始化的工作。
在上面的例子中我初始化了一个列表并放入上下文中,在应用层的代码中可以用以下方式获得这个列表:

  1. //方法1
  2. ServletContext servletContext= request.getServletContext();
  3. ArrayList<String> expressList=(ArrayList<String>)servletContext.getAttribute("expressList");
  4. //方法2
  5. org.springframework.web.context.WebApplicationContext webApplicationContext = org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
  6. ServletContext servletContext2 = webApplicationContext.getServletContext();
  7. ArrayList<String> expressList2=(ArrayList<String>)servletContext2.getAttribute("expressList");

第一个方法是需要有HttpRequest的场合才能使用的。

2,ServletContextAttributeListener

代码:

  1. package com.web.system.listener;
  2. import javax.servlet.ServletContextAttributeEvent;
  3. import javax.servlet.ServletContextAttributeListener;
  4. public class MyServletContextAttributeListener implements ServletContextAttributeListener{
  5. @Override
  6. public void attributeAdded(ServletContextAttributeEvent arg0) {
  7. System.out.println("新增上下文参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  8. }
  9. @Override
  10. public void attributeRemoved(ServletContextAttributeEvent arg0) {
  11. System.out.println("删除上下文参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  12. }
  13. @Override
  14. public void attributeReplaced(ServletContextAttributeEvent arg0) {
  15. System.out.println("修改上下文参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  16. }
  17. }

在web.xml中的配置:

  1. <listener>
  2. <listener-class>com.web.system.listener.MyServletContextAttributeListener</listener-class>
  3. </listener>

监听器中的三个方法分别监听了Servlet上下文的参数在新增、修改、删除时的事件,如果在应用层代码中修改上下文的参数:

  1. request.getSession().getServletContext().setAttribute("testContextAttribute", "abc");
  2. request.getSession().getServletContext().setAttribute("testContextAttribute", "def");
  3. request.getSession().getServletContext().removeAttribute("testContextAttribute");

监听器就可以监听到这些事件并输出:

新增上下文参数,name:testContextAttribute,value:abc 修改上下文参数,name:testContextAttribute,value:abc 删除上下文参数,name:testContextAttribute,value:def

3,HttpSessionListener

代码:

  1. package com.web.system.listener;
  2. import javax.servlet.http.HttpSessionEvent;
  3. import javax.servlet.http.HttpSessionListener;
  4. public class MyHttpSessionListener implements HttpSessionListener{
  5. /**
  6. * 新增session
  7. */
  8. @Override
  9. public void sessionCreated(HttpSessionEvent arg0) {
  10. System.out.println("MyHttpSessionListener Created,sessionId:"+arg0.getSession().getId());
  11. Integer count=null;//session数量
  12. Object sessionCount=arg0.getSession().getServletContext().getAttribute("sessionCount");
  13. if(sessionCount==null){
  14. count=0;
  15. }else{
  16. count=Integer.valueOf(sessionCount.toString());
  17. }
  18. count++;
  19. System.out.println("当前session数:"+count.toString());
  20. arg0.getSession().getServletContext().setAttribute("sessionCount", count);
  21. arg0.getSession().setAttribute("testName", "this is a name");
  22. }
  23. /**
  24. * 销毁session
  25. */
  26. @Override
  27. public void sessionDestroyed(HttpSessionEvent arg0) {
  28. System.out.println("MyHttpSessionListener Destory,sessionId:"+arg0.getSession().getId());
  29. Integer count=null;//session数量
  30. Object sessionCount=arg0.getSession().getServletContext().getAttribute("sessionCount");
  31. if(sessionCount==null){
  32. count=0;
  33. }else{
  34. count=Integer.valueOf(sessionCount.toString());
  35. }
  36. count--;
  37. System.out.println("当前session数:"+count.toString());
  38. arg0.getSession().getServletContext().setAttribute("sessionCount", count);
  39. }
  40. }

在web.xml中的配置:

  1. <listener>
  2. <listener-class>com.web.system.listener.MyHttpSessionListener</listener-class>
  3. </listener>

sessionCreated()方法就是在创建一个session时的监听,具体时间点是在session创建完成之后,所以可以在方法中对刚创建的session进行操作。
在这个例子中,代码维护了一个当前WebService中的session数,当session创建时加一,session销毁时减一,这个session数是放在上下文中的。同时还往当前session中添加了一个叫testName的参数。
这个例子中的session数和testName参数,可以在应用层中的以下代码获得:

  1. String sessionCount=request.getSession().getServletContext().getAttribute("sessionCount").toString();
  2. String testName=request.getSession().getAttribute("testName").toString();

4,HttpSessionAttributeListener

代码:

  1. 1. package com.web.system.listener;
  2. 2.
  3. 3. import javax.servlet.http.HttpSessionAttributeListener;
  4. 4. import javax.servlet.http.HttpSessionBindingEvent;
  5. 5.
  6. 6. public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener{
  7. 7.
  8. 8. @Override
  9. 9. public void attributeAdded(HttpSessionBindingEvent arg0) {
  10. 10. System.out.println(arg0.getSession().getId()+"新增session参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  11. 11.
  12. 12. }
  13. 13.
  14. 14. @Override
  15. 15. public void attributeRemoved(HttpSessionBindingEvent arg0) {
  16. 16. System.out.println(arg0.getSession().getId()+"删除session参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  17. 17.
  18. 18. }
  19. 19.
  20. 20. @Override
  21. 21. public void attributeReplaced(HttpSessionBindingEvent arg0) {
  22. 22. System.out.println(arg0.getSession().getId()+"修改session参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  23. 23.
  24. 24. }
  25. 25.
  26. 26. }

在web.xml中的配置:

  1. 1. <listener>
  2. 2.
  3. 3. <listener-class>com.web.system.listener.MyHttpSessionAttributeListener</listener-class>
  4. 4.
  5. 5. </listener>

这个监听器提供了session参数在新增、修改、删除时的监听,如果在应用层代码中对session参数进行操作:

  1. 1. request.getSession().setAttribute("testContextAttribute", "abc");
  2. 2.
  3. 3. request.getSession().setAttribute("testContextAttribute", "def");
  4. 4.
  5. 5. request.getSession().removeAttribute("testContextAttribute");

监听器就会有如下输出:

26E7704D5B524C997B34E54021D46E44新增session参数,name:testContextAttribute,value:abc 26E7704D5B524C997B34E54021D46E44修改session参数,name:testContextAttribute,value:abc 26E7704D5B524C997B34E54021D46E44删除session参数,name:testContextAttribute,value:def

5,ServletRequestListener

代码:

  1. package com.web.system.listener;
  2. import javax.servlet.ServletRequestEvent;
  3. import javax.servlet.ServletRequestListener;
  4. import javax.servlet.http.HttpServletRequest;
  5. public class MyServletRequestListener implements ServletRequestListener{
  6. @Override
  7. public void requestDestroyed(ServletRequestEvent arg0) {
  8. System.out.println("MyServletRequestListener Destory");
  9. }
  10. @Override
  11. public void requestInitialized(ServletRequestEvent arg0) {
  12. System.out.println("MyServletRequestListener Init");
  13. Integer count=null;//请求数量
  14. Object requestCount=arg0.getServletContext().getAttribute("requestCount");
  15. if(requestCount==null){
  16. count=0;
  17. }else{
  18. count=Integer.valueOf(requestCount.toString());
  19. }
  20. count++;
  21. System.out.println("当前请求数:"+count.toString());
  22. arg0.getServletContext().setAttribute("requestCount", count);
  23. //serverName
  24. String serverName=arg0.getServletRequest().getServerName();
  25. System.out.println("serverName:"+serverName);
  26. //serverPort
  27. int serverPort=arg0.getServletRequest().getServerPort();
  28. System.out.println("serverPort:"+serverPort);
  29. HttpServletRequest servletRequest=(HttpServletRequest)arg0.getServletRequest();
  30. //requestURI
  31. String requestURI=servletRequest.getRequestURI();
  32. System.out.println("requestURI:"+requestURI);
  33. //requestURL
  34. String requestURL=servletRequest.getRequestURL().toString();
  35. System.out.println("requestURL:"+requestURL);
  36. //servletPath
  37. String servletPath=servletRequest.getServletPath();
  38. System.out.println("servletPath:"+servletPath);
  39. //queryString
  40. String queryString=servletRequest.getQueryString();
  41. System.out.println("queryString:"+queryString);
  42. }
  43. }

在xml中的配置:

  1. 1. <listener>
  2. 2.
  3. 3. <listener-class>com.web.system.listener.MyServletRequestListener</listener-class>
  4. 4.
  5. 5. </listener>

requestInitialized()方法就是在一个HttpRequest创建完成时的监听,在该方法中可以对刚组建好的HttpRequest进行操作。
在上面的例子中,代码维护了一个WebService的request请求数并放到了上下文中。另外,方法中还输出了这个请求的ServerName,端口,URL,URI等信息。
如果用户提交了一个这样的请求:

http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/datagrid.do?field=id,code,applyDate,filename,reportType,applyUser,outPath

那么监听器可能会有这样的输出:

MyServletRequestListener Init 当前请求数:19 serverName:localhost serverPort:9080 requestURI:/dangwebx-tst/tms/bms/billingQaReportController/datagrid.do requestURL:http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/datagrid.do servletPath:/tms/bms/billingQaReportController/datagrid.do queryString:field=id,code,applyDate,filename,reportType,applyUser,outPath

6,ServletRequestAttributeListener

代码:

  1. 1. package com.web.system.listener;
  2. 2.
  3. 3. import javax.servlet.ServletRequestAttributeEvent;
  4. 4. import javax.servlet.ServletRequestAttributeListener;
  5. 5. import javax.servlet.http.HttpServletRequest;
  6. 6.
  7. 7. public class MyServletRequestAttributeListener implements ServletRequestAttributeListener{
  8. 8.
  9. 9. @Override
  10. 10. public void attributeAdded(ServletRequestAttributeEvent arg0) {
  11. 11. HttpServletRequest servletRequest=(HttpServletRequest)arg0.getServletRequest();
  12. 12. System.out.println(servletRequest.getRequestURL().toString()+"新增request参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  13. 13.
  14. 14. }
  15. 15.
  16. 16. @Override
  17. 17. public void attributeRemoved(ServletRequestAttributeEvent arg0) {
  18. 18. HttpServletRequest servletRequest=(HttpServletRequest)arg0.getServletRequest();
  19. 19. System.out.println(servletRequest.getRequestURL().toString()+"删除request参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  20. 20.
  21. 21. }
  22. 22.
  23. 23. @Override
  24. 24. public void attributeReplaced(ServletRequestAttributeEvent arg0) {
  25. 25. HttpServletRequest servletRequest=(HttpServletRequest)arg0.getServletRequest();
  26. 26. System.out.println(servletRequest.getRequestURL().toString()+"修改request参数,name:"+arg0.getName()+",value:"+arg0.getValue());
  27. 27.
  28. 28. }
  29. 29.
  30. 30. }

在web.xml中的配置:

  1. 1. <listener>
  2. 2.
  3. 3. <listener-class>com.web.system.listener.MyServletRequestAttributeListener</listener-class>
  4. 4.
  5. 5. </listener>

这个监听中提供了对HttpRequest的参数在进行新增、修改、删除时的监听,如果在应用层代码中修改请求的参数:

  1. 1. request.setAttribute("testContextAttribute", "abc");
  2. 2.
  3. 3. request.setAttribute("testContextAttribute", "def");
  4. 4.
  5. 5. request.removeAttribute("testContextAttribute");

那么监听器可能会有这样的输出:

http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do新增request参数,name:testContextAttribute,value:abc http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do修改request参数,name:testContextAttribute,value:abc http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do删除request参数,name:testContextAttribute,value:def

在实际项目中,HttpRequestAttribute的监听器输出的内容可能比想象中的要多,因为不管是java还是项目中的其他组件都有可能对请求进行一些必要的装配,所以可能会出现一些这样的输出:

http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do新增request参数,name:javax.servlet.jsp.jstl.fmt.locale.request,value:zh_CN http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do新增request参数,name:javax.servlet.jsp.jstl.fmt.localizationContext.request,value:org.springframework.web.servlet.support.JstlUtils$SpringLocalizationContext@486f7c41 http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do删除request参数,name:__spring_security_scpf_applied,value:true http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do删除request参数,name:__dangwebx_context_persistence_filter,value:true http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do删除request参数,name:encodingFilter.FILTERED,value:true http://localhost:9080/dangwebx-tst/tms/bms/billingQaReportController/list.do删除request参数,name:openSessionInViewFilter.FILTERED,value:true


以上就是关于Servlet监听器的几个最简单的例子,另外,在SpringFramework中对这些监听器简直玩出了花,可以看看。