基本方法:
基本的方法,网上到处都是,在 java 中就是在 web.xml 注册一个 Listener ,如下:
<listener>
<listener-class>xp.web.SessionCounter</listener-class>
</listener>
SessionCounter.java 实现 javax.servlet.http.HttpSessionListener 接口,分别在 sessionCreated 方法和 sessionDestroyed 方法中处理 session 数目。
这样的方法有一定的问题:
1 、对于真正从网页访问的和搜索引擎的 spider 无法区分。
2 、当 Tomcat 重启时,加载了上次持久化的 session 时,无法准确计算在线数。
第二个问题我们可以不予考虑,这是 tomcat 容器实现不标准的问题,我们要解决的是的第一个问题,如何知道你的访问的是真实的。
用 js 绕过搜索引擎 :
做过 pv 统计的都知道,可以用 script 的方式得到你真实的 pageView 数目,我们现在要做的就是这样的一件事情,我们在所有的页面都加入一段话:
<script type="text/javascript">
document.write ("<iframe src='/sessionCountServlet' width=0 height=0 frameborder=no border=0 MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=no></iframe>");
</script>
然后我们写上一个 servlet 来记录这些真正的访问者。
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionCounterServlet extends HttpServlet {
public SessionCounterServlet() {
super();
}
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
process(request, response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
process(request, response);
}
public void process(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
SessionCounter.put(request.getSession().getId());
}
}
我们可以看到这个 servlet 只是做了一件事情,在 process 里面做了 SessionCounter.put(request.getSession().getId()); 这个动作。
我们来看看我们的 SessionCounter 做了些什么:
import javax.servlet.http.*;
import java.util.Hashtable;
public class SessionCounter implements HttpSessionListener {
public SessionCounter() {
}
public static Hashtable m_real = new Hashtable();
private static long count = 0;
public void sessionCreated(HttpSessionEvent e) {
count++;
}
public void sessionDestroyed(HttpSessionEvent e) {
if (count > 0) {
count--;
}
m_real.remove(e.getSession().getId());
}
public static long getSessionCount() {
return count;
}
public static void put(String sessionId){
m_real.put(sessionId,"1");
}
public static int getRealCount(){
return m_real.size();
}
}
我们记录了一个静态的 hash 表来记录激活状态的 sessionid ,并在 session 销毁的时候将这个 sessionid 置为空。
怎么把 servlet 配置到 web 应用中我就不罗唆了。