一、web.xml文件
<?xml version="1.0" encoding="ISO-8859-1"?>
web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
这注册了ClickstreamFilter并设置其处理*.jsp和*.html来的请求。这也将ClickstreamLogger注册为一个监听器以在应用事件发生时接受他们。
二、既是ServletContextListener又是 HttpSessionListener监听器ClickstreamLogger类
function TempSave(ElementID) { CommentsPersistDiv.setAttribute("CommentContent",document.getElementById(ElementID).value); CommentsPersistDiv.save("CommentXMLStore"); } function Restore(ElementID) { CommentsPersistDiv.load("CommentXMLStore"); document.getElementById(ElementID).value=CommentsPersistDiv.getAttribute("CommentContent"); }package com.java3z.examples; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class ClickstreamLogger implements ServletContextListener, HttpSessionListener { Map clickstreams = new HashMap(); public ClickstreamLogger() { // System.out.println("ClickstreamLogger constructed"); } public void contextInitialized(ServletContextEvent sce) { // System.out.println("ServletContext Initialised"); sce.getServletContext().setAttribute("clickstreams", clickstreams); } public void contextDestroyed(ServletContextEvent sce) { sce.getServletContext().setAttribute("clickstreams", null); // System.out.println("ServletContext Destroyed"); } public void sessionCreated(HttpSessionEvent hse) { // System.out.println("Session Created"); HttpSession session = hse.getSession(); Clickstream clickstream = new Clickstream(); session.setAttribute("clickstream", clickstream); clickstreams.put(session.getId(), clickstream); } public void sessionDestroyed(HttpSessionEvent hse) { // System.out.println("Session Destroyed"); HttpSession session = hse.getSession(); Clickstream stream = (Clickstream)session.getAttribute("clickstream"); clickstreams.remove(session.getId()); System.out.println("Final session clickstream:\n" + stream); } } ClickstreamLogger类在servlet环境创建时设置全局属性getServletContext.setAttribute("clickstreams", clickstreams),一个
Map,在用户访问网站时设置会话属性session.setAttribute("clickstream", clickstream),并将可记录会话数据的对象clickstream
放入Map,以便在JSP页面中输出网站访问者的信息。 三、过滤器ClickstreamFilter类
package com.java3z.examples;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class ClickstreamFilter implements Filter {
protected FilterConfig filterConfig;
private final static String FILTER_APPLIED = "_clickstream_filter_applied";
public void init(FilterConfig config) throws ServletException {
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 确保该过滤器在每次请求中只被使用一次
if (request.getAttribute(FILTER_APPLIED) == null) {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
HttpSession session = ((HttpServletRequest)request).getSession();
Clickstream stream = (Clickstream)session.getAttribute("clickstream");
stream.addRequest(((HttpServletRequest)request));
}
// 传递请求
chain.doFilter(request, response);
}
public void destroy() { }
}
doFilter()方法取得用户的session,从中获取Clickstream,并将当前请求数据加到Clickstream中。其中使用了一个特殊的FILTER_APPLIED标记属性来标注此过滤器是否已经被当前请求使用(可能会在请求调度中发生)并且忽略所有其他的过滤器行为。
</td> </tr> <tr>
四、保存请求数据的Clickstream类package com.java3z.examples; import java.util.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Clickstream implements Serializable { List clickstream = new ArrayList(); String hostname = null; HttpSession session = null; String initialReferrer = null; Date start = new Date(); Date lastRequest = new Date(); boolean bot = false;//是否是机器人访问 public Clickstream() { } public void addRequest(HttpServletRequest request) { lastRequest = new Date(); if (hostname == null) { hostname = request.getRemoteHost(); session = request.getSession(); } // if this is the first request in the click stream if (clickstream.size() == 0) { // setup initial referrer if (request.getHeader("REFERER") != null) { initialReferrer = request.getHeader("REFERER"); } else { initialReferrer = ""; } // decide whether this is a bot bot = BotChecker.isBot(request, this); } clickstream.add(request.getServerName() + (request.getServerPort() != 80 ? ":" + request.getServerPort() : "") + request.getRequestURI() + (request.getQueryString() != null ? "?" + request.getQueryString() : "")); // System.out.println(this.toString()); } public String getHostname() { return hostname; } public boolean isBot() { return bot; } public void setBot(boolean value) { this.bot = value; } public HttpSession getSession() { return session; } public String getInitialReferrer() { return initialReferrer; } public Date getStart() { return start; } public Date getLastRequest() { return lastRequest; } public List getStream() { return clickstream; } public String toString() { StringBuffer output = new StringBuffer(); output.append("Clickstream for: " + hostname + "\n"); output.append("Session ID: " + (session != null ? session.getId() + "" : "") + "\n"); output.append("Initial Referrer: " + initialReferrer + "\n"); output.append("Stream started: " + start + "\n"); output.append("Last request: " + lastRequest + "\n"); long streamLength = lastRequest.getTime() - start.getTime(); output.append("Stream length:" + (streamLength > 3600000 ? " " + (streamLength / 3600000) + " hours" : "") + (streamLength > 60000 ? " " + ((streamLength / 60000) % 60) + " minutes" : "") + (streamLength > 1000 ? " " + ((streamLength / 1000) % 60) + " seconds" : "") + "\n"); Iterator clickstreamIt = clickstream.iterator(); int count = 0; while (clickstreamIt.hasNext()) { count++; output.append(count + ": " + clickstreamIt.next() + "\n"); } return output.toString(); } }五、是机器人吗?
BotChecker类用来确定客户端是否是一个机器人。package com.java3z.examples; import java.util.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class BotChecker { public static String[] botHosts = {"inktomi.com", "inktomisearch.com", "googlebot.com", "linuxtoday.com.au"}; public static boolean isBot(HttpServletRequest request, Clickstream stream) { String requestURI = request.getRequestURI(); // if it requested robots.txt, it's a bot if (requestURI.indexOf("robots.txt") >= 0) { return true; } // it requested a RSS feed from our backend, it's a bot if (requestURI.indexOf("/backend/") >= 0) { return true; } for (int i = 0; i < botHosts.length; i++) { if (request.getRemoteHost().indexOf(botHosts[i]) >= 0) { return true; } } return false; } } 六、测试:请下载测试这个WEB应用的所有文件。
↑返回目录
前一篇: 网络对战的国际象棋源码
后一篇: JSF实例学习--JSF Weekly 电子报订阅