Java监听器介绍和入门
Web服务器可以通过监听器对ServletContext、HttpServlet、ServletRequest这三个域对象进行监听。下面是监听器实现学习的路线
配置监听器
以ServletContextListener为例来实现监听器的基本功能
先创建一个Java类,然后使用ServletContextListener接口
public void contextInitialized(ServletContextEvent sec)该方法是监听器的启动方法
public void contextDestroyed(ServletContextEvent sec)当项目停止或者被移除,该方法就销毁监听器,也就是俗称的销毁方法
package com.zhumeng.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyFirstListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent sec) {// TODO Auto-generated method stub System.out.println("被销毁了"); } @Override public void contextInitialized(ServletContextEvent sec) { // TODO Auto-generated method stub System.out.println("启动"); } }
写Java类监听器后,就要对监听器进行配置,通过Web项目中的xml文件来配置
1.默认项目的初始页面为index.jsp(不用创建)
2.使用listener标签,填写格式为”包名”+”监听器类名”。非常简单的配置方式
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebListenerDemo2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>com.zhumeng.listener.MyFirstListener</listener-class> </listener> </web-app>
接下来就可以启动服务器来查看控制台输出的内容
显示”启动”表示该监听器的初始化方法正常执行,也说明监听器启动配置成功。接下来就可以停止服务器,控制台就显示出”被销毁了”,说明监听器被正常销毁
监听器的注册和销毁顺序
Web项目中通常有多个监听器,监听器的实现和销毁都是有顺序的,这些顺序和xml中配置监听器的位置有关系
监听器的分类
请参考思维导图的解析
ServletContext:
在xml文件中设置初始化参数,设置好之后可以通过ServletContextListener中的ContextInitialized方法来读取xml文件中设置好的参数,然后存放到ServletContext对象中。这样就能使Web项目一启动就可以把必要的信息存储在ServletContext中。
当关闭的时候就可以对一些链接,比如数据库链接,文件链接进行处理
在xml文件中配置参数可以通过<context-param>标签来实现,<param-name>参数名、<param-value>参数值。这样设置的好处就是以后维护方便,只需要在xml文件中修改参数即可。
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebListenerDemo2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>com.zhumeng.listener.MyServletContextListener</listener-class> </listener> <context-param> <param-name>AppName</param-name> <param-value>Listener</param-value> </context-param> <context-param> <param-name>version</param-name> <param-value>1.0</param-value> </context-param> </web-app>
package com.zhumeng.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub String appName = (String) sce.getServletContext().getAttribute("appName"); String version = (String) sce.getServletContext().getAttribute("version"); System.out.println("销毁名称:"+appName); System.out.println("销毁版本:"+version); } @Override public void contextInitialized(ServletContextEvent sce) { String appName = sce.getServletContext().getInitParameter("AppName"); String version = sce.getServletContext().getInitParameter("version"); sce.getServletContext().setAttribute("appName", appName); sce.getServletContext().setAttribute("version", version); System.out.println("启动名称:"+appName); System.out.println("启动版本:"+version); }}
通过一个Servlet类来测试是否将数值存入到ServletContext域中
package com.imooc.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class MyServletContextListener */ @WebServlet("/MyServletContextListener") public class MyServletContextListener extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Object name = this.getServletContext().getAttribute("appName"); System.out.println(name); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
注意:这里销毁的是不是初始化参数,而是保存到ServletContext域中的信息。
HttpSession:
当用户第一次通过浏览器对服务器进行访问的时候,服务器就会创建一个会话对象(HttpSession)。这个会话存储的是用户的专有信息,例如用户名,密码、权限等等。一个会话对象就代表一个用户,也就是说当一个用户离开后对应的会话对象也被消除
HTTPSession对应的接口是HttpSessionListener
package com.zhumeng.listener; import java.util.Date; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent hrc) { // 获得session编号 String id = hrc.getSession().getId(); //获取创建时间 Date time = new Date(hrc.getSession().getCreationTime()); System.out.println("创建编号:"+id); System.out.println("创建时间:"+time); } @Override public void sessionDestroyed(HttpSessionEvent hrc) { // 监听销毁对象编号 String id = hrc.getSession().getId(); System.out.println("销毁编号:"+id); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebListenerDemo2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>com.zhumeng.listener.MyHttpSessionListener</listener-class> </listener> <session-config> <session-timeout>1</session-timeout> </session-config> </web-app>
<session-config>标签是设置1分钟后会话对象自动销毁。配置好xml后还要创建一个jsp页面,内容空白即可。
当使用两款不同的浏览器访问index.jsp页面的时候,就创建了两个不同的id。1分钟后两个id自动销毁。
ServletRequest:
用户每一次发出一个请求,都会生成一个请求对象。通过监听器可以监听请求对象,然后对用户请求的内容进行分析
因为获得的是Http请求对象,所以要进行转型。
获得请求路径的目的是可以知道请求的资源或者操作的内容等等
package com.zhumeng.listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; public class MyServletRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sce) { // TODO Auto-generated method stub System.out.println("销毁!"); } @Override public void requestInitialized(ServletRequestEvent sce) { HttpServletRequest request = (HttpServletRequest)sce.getServletRequest(); // 获得请求路径 String path = request.getRequestURI(); String par = request.getParameter("par"); System.out.println("初始化path:"+path); System.out.println("初始化请求参数:"+par); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebListenerDemo2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>com.zhumeng.listener.MyServletRequestListener</listener-class> </listener> </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>测试</title> </head> <body> <h1>首页</h1> <label> <a href="index2.jsp?par=java" target="_blank">初始化</a> </label> </body> </html>
index2.jsp的内容空白即可,主要是体现index1发出请求传递参数的时候,监听器能监听到并且获取参数。值得一提的是,初始化结束后就立刻执行销毁方法,根之间的监听器有点差别。
域对象中属性的创建、替换和消除事件监听器
这类监听器主要对对象中的指定的属性进行监听,一旦发现该属性发送变化,例如增加、删除、修改等,就会做出相对应的操作
package com.zhumeng.listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; public class MyServletContextAttributeListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent sce) { // 属性添加 System.out.println("add...name:"+sce.getName()); System.out.println("add...value:"+sce.getValue()); System.out.println(); } @Override public void attributeRemoved(ServletContextAttributeEvent sce) { //属性删除 System.out.println("removed...name:"+sce.getName()); System.out.println("removed...value:"+sce.getValue()); System.out.println(); } @Override public void attributeReplaced(ServletContextAttributeEvent sce) { // 属性修改 System.out.println("replaced...name:"+sce.getName()); System.out.println("replaced...value:"+sce.getValue()); System.out.println(); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebListenerDemo2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>com.zhumeng.listener.MyServletContextAttributeListener</listener-class> </listener> </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <a href="index3.jsp">点击</a> <a href="index4.jsp">删除</a> <a href="index5.jsp">修改</a> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% application.setAttribute("java", "java入门到放弃"); application.setAttribute("C","C入门到放弃"); application.setAttribute("python", "py入门到放弃"); %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>属性测试</title> </head> <body> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <% application.removeAttribute("java"); %> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>Insert title here</title> </head> <body> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% application.setAttribute("java", "精通"); Object java = application.getAttribute("java"); Object C = application.getAttribute("C"); Object python = application.getAttribute("python"); %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> </body> </html>