监听器(Listener)是J2EE的组件之一,用于监听Web应用对象的行为,通过监听其变化执行指定代码。
相较于过滤器,监听器的主体是Web应用对象属于被动执行,而过滤器是检测URL地址对其进行拦截属于主动执行。
监听对象
- ServletContext-全局对象
- HttpSession-用户会话
- ServletRequest-用户请求
监听器主要对这三种对象即属性进行监听
示例:
package com.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class WebListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象已创建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<listener>
<listener-class>com.listener.WebListener</listener-class>
</listener>
</web-app>
实现监听器首先需要实现Listener接口,不通的监听对象需要实现不通的Listener接口;每个接口都有自己独立的方法,当对象发生改变时就会按方法执行;最后需要再web.xml中进行配置,增加标签<listener>
。
监听器接口
内置对象监听接口
- ServletContextListener - 监听ServletContext对象的创建和销毁
- HttpSessionListener - 监听HttpSession对象创建和销毁
- ServletRequestListener - 监听HttpServletRequest对象的创建和销毁
内置对象属性监听接口
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
对于内置对象监听接口主要实现方法包括对象的创建和销毁,而内置对象属性监听接口主要实现对象属性的新增,删除与修改三种方法。接口方法中的参数为Web应用对象的事件类,可根据该参数获取对象的相关信息。
示例:
package com.listener;
import javax.servlet.*;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class WebListener implements ServletContextListener, HttpSessionListener, ServletRequestListener,
ServletContextAttributeListener, HttpSessionAttributeListener, ServletRequestAttributeListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象已创建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象已销毁");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("ServletRequest对象已销毁");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("ServletRequest对象已创建");
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("HttpSession对象已创建");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("HttpSession对象已销毁");
}
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
String attr = (String) servletContextAttributeEvent.getServletContext().getAttribute("sc-attr");
System.out.println("ServletContext属性sc-attr:" + attr);
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
String attr = (String) servletRequestAttributeEvent.getServletRequest().getAttribute("req-attr");
System.out.println("ServletRequest属性req-attr:" + attr);
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
}
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
String sessionId = httpSessionBindingEvent.getSession().getId();
String attr = (String) httpSessionBindingEvent.getSession().getAttribute("s-attr");
System.out.println("HttpSessionId:" + sessionId + ",session属性s-attr:" + attr);
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
}
}
package com.listener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class WebServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getServletContext().setAttribute("sc-attr", "sc-value");
req.getSession().setAttribute("s-attr", "s-value");
req.setAttribute("req-attr", "req-value");
resp.getWriter().println("Test Listener");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>webServlet</servlet-name>
<servlet-class>com.listener.WebServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>webServlet</servlet-name>
<url-pattern>/webServlet</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.listener.WebListener</listener-class>
</listener>
</web-app>
通过监听器的操作可以更好理解Web应用对象的生命周期。当服务启动时ServletContext全局对象创建,在开始访问映射地址时首先判断是否存在用户会话,若不存在则会创建用户会话session,同时创建ServletRequest对象,当完成响应之后服务器请求对象自动销毁,在不设置session存活时间的情况下会在30分钟内自动销毁,而全局对象会在服务停止或重启时销毁。