listener问题
小姜哥 博客专家认证 2010-12-30 08:50:20 今天用listener做了一个网站计数器,功能是记录历史访问量和当前在线人数。代码如下:
web.xml:<context-param>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<context-param>
<description>web counter</description>
<param-name>counterPath</param-name>
<param-value>connter.txt</param-value>
</context-param>
<listener>
<description>implements ServletContextListener</description>
<listener-class>com.cs.listener.CounterListener</listener-class>
</listener>
<listener>
<description>implements HttpSessionListener</description>
<listener-class>com.cs.listener.SessionListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
CounterListener.javapackage com.cs.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class CounterListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent evt) {
FileOperator fo = new FileOperator();
String file = evt.getServletContext().getInitParameter("counterPath");
String fileLocation = evt.getServletContext().getRealPath(file);
long currentRecord = fo.readFile(fileLocation);
evt.getServletContext().setAttribute("web_counter", currentRecord);
}
public void contextDestroyed(ServletContextEvent evt) {
long currentRecord = (Long)evt.getServletContext().getAttribute("web_counter");
FileOperator fo = new FileOperator();
String file = evt.getServletContext().getInitParameter("counterPath");
String fileLocation = evt.getServletContext().getRealPath(file);
fo.writeFile(fileLocation, currentRecord);
}
}
SessionListener.javapackage com.cs.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class SessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent evt) {
long currentRecord = ((Long)evt.getSession().getServletContext().getAttribute("web_counter"));
currentRecord++;
evt.getSession().getServletContext().setAttribute("web_counter",currentRecord);
long online = 1;
Long hisOnline = (Long)evt.getSession().getServletContext().getAttribute("online_counter");
if(hisOnline != null){
online += hisOnline;
}
evt.getSession().getServletContext().setAttribute("online_counter",online);
System.out.println("online :" + online);
}
public void sessionDestroyed(HttpSessionEvent evt) {
long online = (Long)evt.getSession().getServletContext().getAttribute("online_counter");
online--;
evt.getSession().getServletContext().setAttribute("online_counter",online);
System.out.println("online :" + online);
}
}
JSP中的代码:<body>
历史访问量:<%= (Long)application.getAttribute("web_counter")%>
<br>
当前在线人数:<%=application.getAttribute("online_counter") %>
</body>
问题是:页面访问的时候数据都能读的出来,但是浏览器窗口关闭的时候sessionDestroyed并没有执行(应该说是没有马上执行)。反正sessionDestroyed中的打印语句没打印出出东西,在另外一个浏览器(opera和maxthon两个浏览器)中刷新也没有反应。不知过了多久我刷新了一下,当前在线人数竟然变成负数了。
挺晕的,我想 当我关掉浏览器窗口的时候session是不是就该销毁。服务器端是怎么知道客户端浏览器关闭的? 负数是怎么出现的,我想无论怎么都不会是负数啊。
另外一个问题在web.xml中是设置session生命周期单位是什么?? 时间是怎么算的,比方说设置30分钟,是从创建时起30分钟还是从客户端没有活动起30分钟。
都什么情况下session会被销毁??