1、监听器
(1)什么是监听器
servlet规范当中定义的一种特殊的组件,用来监听servlet容器产生的事件并进行相应的处理。
事件主要有两大类:
1)生命周期相关的事件:
当容器创建或者销毁了request,session,servletContext(servlet上下文)时产生的事件。
2)绑订相关的事件:
当容器调用了request,session,servlet上下文的setAttribute,removeAttribute方法时产生的事件。
(2)如何写一个监听器
step1,写一个java类,实现相应的监听器接口。(依据事件类型选择相应的接口,比如监听session的创建或者销毁,使用HttpSessionListener接口)
step2,在监听器接口方法里面,编写相应的处理逻辑。
step3,注册(在web.xml文件里面,配置监听器)。
(3)servlet上下文
1)什么是servlet上下文?
容器一启动,会为每一个web应用创建唯一的一个符合ServletContext接口要求的对象。该对象就是servlet上下文。
该对象有两个特点:
a,唯一性:一个web应用一个servlet上下文。
b,一直存在: 只要容器不关闭或者应用没有被卸载,servlet上下文会一直存在。
2)如何获得servlet上下文
可以通过GenericServlet,ServletConfig,FilterConfig,HttpSession提供的getServletContext方法来获得servlet上下文。
3) 作用
a,绑订数据
setAttribute(String name,Object obj);
Object getAttribute(String name);
removeAttribute(String name);
注意:
request,session,servlet上下文都提供了绑订数据相关的方法,但是有两个区别:
区别1:绑订数据生存的时间不一样,servlet上下文 > session > request。
区别2: 数据共享的范围不一样。
request对象绑订的数据只有同一个请求所涉及的各个组件可以访问(转发,过滤器);
session对象绑订的数据只有同一个会话所涉及的各个组件可以访问;
servlet上下文绑订的数据是同一个应用所有的组件都可以访问。
尽量优先使用生命周期短的,比如能用request解决,就不要用session。
b,访问全局的初始化参数(同一个应用内部的所有的servlet/filter都可以访问的初始化参数)。
step1,使用
<context-param>
<param-name>company</param-name>
<param-value>name</param-value>
</context-param>
step2,使用
String ServletContext.getInitParameter( "company");
c,获得实际部署时的物理路径
String getRealPath(String path);
2、案例:统计在线人数
index.jsp:
<%@page pageEncoding="utf-8"
contentType="text/html;charset=utf-8" %>
<html>
<head></head>
<body style="font-size:40px;">
这是首页<br/>
当前系统在线人数是:
<%=application.getAttribute("count") %>
<br/>
<a href="logout" target="_blank" rel="external nofollow" >退出</a>
</body>
</html>
web.xml添加配置:
<listener>
<listener-class>web.CountListener</listener-class>
</listener>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>web.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
LogoutServlet.java:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LogoutServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
session.invalidate();//销毁session
}
}
CountListener.java:
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class CountListener implements HttpSessionListener{
private int count = 0; // 计数器
/*
* session一创建,容器就会调用sessionCreated方法。
* HttpSessionEvent:事件对象
*/
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("session created.");
count ++;
HttpSession session = arg0.getSession();
ServletContext sctx = session.getServletContext();
//将人数(count)绑订到servlet上下文
sctx.setAttribute("count", count);
}
/*
* session销毁之后,容器会调用sessionDestroyed方法。
*/
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("session destroyed.");
count --;
HttpSession session = arg0.getSession();
ServletContext sctx = session.getServletContext();
//将人数(count)绑订到servlet上下文
sctx.setAttribute("count", count);
}
}