1.什么是Servlet监听器?
先来看看什么是监听器。监听器是专门用于对其它对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时立即采取相应的行动。Servlet监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序的ServletContext,HttpSession和ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。
按监听的事件类型Servlet监听器可分为如下三种类型:
- 监听域对象自身的创建和销毁的事件监听器
- 监听域对象中的属性的增加和删除的事件监听器
- 监听绑定到HtppSession域中的某个对象的状态的事件监听器
2.域对象创建和销毁的事件监听器
域对象创建和销毁的事件监听器就是用来监听ServletContext,HttpSession,HttpServletRequest这三个对象的创建和销毁事件的监听器。域对象的创建和销毁时机:
- ServletContext:当web服务器启动时为每个web应用程序创建相应的ServletContext对象,web服务器关闭时为每个web应用程序销毁相应的ServletContext对象。
- HttpSession:浏览器开始与服务器会话时创建,调用HttpSession.invalidate();超过了session的最大有效时间间隔;服务器进程被停止。
- ServletRequest:每次请求开始时创建,每次访问结束后销毁。
3.如何编写Servlet监听器?
- Servlet规范为每种事件监听器都定义了相应的接口,编写事件监听程序只需要实现这些接口。
- 在web.xml中进行注册,web服务器按照它们在web.xml中的注册顺序来加载和执行这些Servlet事件监听器。
4.ServletContextListener接口
ServletContextListener接口用于监听ServletContext对象的创建和销毁事件。创建一个Session时,激发sessionCreated(HttpSessionEvent se)方法,销毁一个Session时,激发sessionDestroyed(HttpSessionEvent se)方法。
编写监听器,代码如下:
package com.javaweb.Listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class servletContextListenerTest implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext对象被创建"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext对象被销毁"); } }
在web.xml中进行配置:
<listener> <description>ServletContextListener</description> <listener-class>com.javaweb.Listener.servletContextListenerTest</listener-class> </listener>
ServletContextListener是最常用的Listener,可以在当前web应用被加载时对当前web应用的相关资源进行初始化操作;创建数据库连接池,创建Spring的IOC容器,读取当前web应用的初始化参数。
5.通过Listener理解域对象生命周期
5.1 request:是一个请求,当一个响应返回时,即被销毁,当发送一个请求时被创建。
index.jsp
<body> <a href="Listener/test.jsp">to test page</a> <% request.setAttribute("resquestKey","requestValue"); %> </body>
test.jsp
<body> <%= request.getAttribute("resquestKey") %> </body>
运行index.jsp,发送一个请求,返回一个响应页面,
request请求被销毁。此时在index.jsp页面设置的属性request.setAttribute("resquestKey","requestValue");在test.jsp页面中获取不到对应的属性值,入下:
可以通过请求转发(请求转发只有一个request)实现上述功能:
<% request.setAttribute("resquestKey","requestValue"); %> <jsp:forward page="/Listener/test.jsp"></jsp:forward>
在index.jsp页面点击超链接到TestServlet,在TestServlet中将请求转发到test.jsp页面。中间涉及到的是一个request请求。
index.jsp
<body> <a href="TestServlet">testServlet</a> </body>
testServlet.java
package com.javaweb.Listener; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class testServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("requestKey", "requestValue2"); request.getRequestDispatcher("/Listener/test.jsp").forward(request, response); } }
test.jsp
<body> <%= request.getAttribute("requestKey") %> </body>
web.xml中进行配置:
<servlet> <servlet-name>testServlet</servlet-name> <servlet-class>com.javaweb.Listener.testServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>/TestServlet</url-pattern> </servlet-mapping>
运行后可以获得设置的request属性值。
若将testServlet.java中的请求转发request.getRequestDispatcher("/Listener/test.jsp").forward(request, response);改为请求重定向response.sendRedirect("/Listener/test.jsp");则涉及到两个request请求。
5.2 session:当第一次访问web应用的一个JSP或Servlet时,且该JSP或servelet中还需要创建session对象,此时服务器会创建一个session对象。
session销毁:session过期;直接调用session的invalidate方法;当前web应用被卸载。
session过期:
<% HttpSession session=request.getSession(true); session.setMaxInactiveInterval(10); %>
session的invalidate方法:
<% HttpSession session=request.getSession(true); session.invalidate(); %>
关闭浏览器,并不意味着session被销毁,还可以通过sessionid找到服务器中的session对象。
5.3 application:贯穿于当前的web应用的生命周期,当前web应用被加载时创建application对象,当前web应用被卸载时销毁application对象。