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会被销毁??

...全文
123 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
cfd406635982 2010-12-31
  • 打赏
  • 举报
回复
如果监听器没有之行的话
根据我有次的经验把它的配置放到web.xml的最前面试试
我曾经出现过一次这样的问题
小姜哥 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cfd406635982 的回复:]
如果监听器没有之行的话
根据我有次的经验把它的配置放到web.xml的最前面试试
我曾经出现过一次这样的问题
[/Quote]

监听器执行了 就是sessionDestroyed方法不是在浏览器关掉之后就执行的 不知道过了多久 就执行了
小姜哥 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xiaohuaxiaofeng 的回复:]
package com.qiter.listener;

import java.util.Date;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet……
[/Quote]

老大 我是想知道我的sessionDestroyed方法是什么时间调用的 ,好像是也调用了 但是是关掉浏览器之后的一段时间之后 session的默认时间是30分钟吧 我没设置 但关掉浏览器之后不到30分钟在线认识就减少了 我是自己做实验的 用两个浏览器 也就是说服务器还是知道了浏览器关掉了 而不是session过期了
小姜哥 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xiaoye2892 的回复:]
引用 3 楼 tt361 的回复:
引用 1 楼 xiaoye2892 的回复:
客户端没有活动30分钟
关掉浏览器session还是存在的 在服务器端 服务器端不知道浏览器关闭


关掉浏览器之后服务器端不知道客户端已经关掉了 那服务器端要等待session过期是么 也就是说我们关掉浏览器三十分钟之后 如果我们设置的session时间是30分钟的话


那要看你在关掉以前是不是……
[/Quote]

那浪费了好多内存 我们访问结束之后30分钟服务器才销毁 session 又没什么好的办法 当浏览器关掉是 服务器就可以感知到
xiaohuaxiaofeng 2010-12-31
  • 打赏
  • 举报
回复
package com.qiter.listener;

import java.util.Date;

import javax.servlet.ServletContext;
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+"秒");
}

}
你说的题目我做过,呵呵!!!
happyfmy 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tt361 的回复:]
引用 1 楼 xiaoye2892 的回复:
客户端没有活动30分钟
关掉浏览器session还是存在的 在服务器端 服务器端不知道浏览器关闭


关掉浏览器之后服务器端不知道客户端已经关掉了 那服务器端要等待session过期是么 也就是说我们关掉浏览器三十分钟之后 如果我们设置的session时间是30分钟的话
[/Quote]

那要看你在关掉以前是不是活动的 这个时间也算上去的
小姜哥 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xiaoye2892 的回复:]
客户端没有活动30分钟
关掉浏览器session还是存在的 在服务器端 服务器端不知道浏览器关闭
[/Quote]

关掉浏览器之后服务器端不知道客户端已经关掉了 那服务器端要等待session过期是么 也就是说我们关掉浏览器三十分钟之后 如果我们设置的session时间是30分钟的话
happyfmy 2010-12-30
  • 打赏
  • 举报
回复
客户端没有活动30分钟
关掉浏览器session还是存在的 在服务器端 服务器端不知道浏览器关闭

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧