今天用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会被销毁??
<?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会被销毁??
解决方案 »
- 严重: Servlet.service() for servlet [jsp] in context with path [/scores]
- 为什么同事拷贝给我的web项目import到Myeclipse以后项目名上面有一个黑色的“米”型错误?
- JAVAEE API
- 大家来投个票吧----大家现在最常用的浏览器是什么?
- Query方法求助
- JBoss 5.0启动错误
- 修改类文件,tomcat自动重启报错,请教高手
- 请问数据库的驱动(MSSQL或MYSQL)应该放在哪个目录下阿??
- struts和jspsmartupload一起怎么用?
- weblogic高手看过来!
- MyEclipse中使用MyEclipse Database Explorer prespective工具连接Oracle数据库
- 关于jsp向servlet传值的问题
关掉浏览器session还是存在的 在服务器端 服务器端不知道浏览器关闭
根据我有次的经验把它的配置放到web.xml的最前面试试
我曾经出现过一次这样的问题
关掉浏览器之后服务器端不知道客户端已经关掉了 那服务器端要等待session过期是么 也就是说我们关掉浏览器三十分钟之后 如果我们设置的session时间是30分钟的话
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
*
* 统计用户访问总数
*
*/
public class CountUserListener implements HttpSessionListener{
private Date begin;
public void sessionCreated(HttpSessionEvent event) {
HttpSession session = event.getSession();
ServletContext application = event.getSession().getServletContext();
int count = 10000;
if(application.getAttribute("count")!=null){
count = Integer.parseInt(
application.getAttribute("count").toString()
);
}
count++;
application.setAttribute("count", new Integer(count));
Date begin = new Date();
session.setAttribute("begin", begin);
} public void sessionDestroyed(HttpSessionEvent event){
HttpSession session = event.getSession();
Date begin = (Date)session.getAttribute("begin");
Date end = new Date();//现在销毁的时间
long time = end.getTime()-begin.getTime();//在线时间单位为毫秒
int s = (int)time/1000; //秒
System.out.println("此用户在线时间为"+s+"秒");
}}
你说的题目我做过,呵呵!!!
那浪费了好多内存 我们访问结束之后30分钟服务器才销毁 session 又没什么好的办法 当浏览器关掉是 服务器就可以感知到
老大 我是想知道我的sessionDestroyed方法是什么时间调用的 ,好像是也调用了 但是是关掉浏览器之后的一段时间之后 session的默认时间是30分钟吧 我没设置 但关掉浏览器之后不到30分钟在线认识就减少了 我是自己做实验的 用两个浏览器 也就是说服务器还是知道了浏览器关掉了 而不是session过期了
监听器执行了 就是sessionDestroyed方法不是在浏览器关掉之后就执行的 不知道过了多久 就执行了