随笔 - 154  文章 - 60  trackbacks - 0
<2007年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

声明:

该blog是为了收集资料,认识朋友,学习、提高技术,所以本blog的内容除非声明,否则一律为转载!!

感谢那些公开自己技术成果的高人们!!!

支持开源,尊重他人的劳动!!

常用链接

留言簿(3)

随笔分类(148)

随笔档案(143)

收藏夹(2)

其他

学习(技术)

观察思考(非技术)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

偶得

看了网上一篇译文《Servlet 2.3 过滤器编程》原文 《Filter code with Servlet 2.3 model 》出自http://www.javawold.com/。里面讲了四个例子,有三个意思不大,没有仔细看。
   下面这个过滤器示例跟踪用户请求,向网络管理员报告谁在她的网站上以及每个用户正在访问那个页面。测试结果图如下:

一、web.xml文件
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

<web-app>
<!-- CLICKSTREAM LOGGER -->
<filter>
  <filter-name>clickstreamFilter</filter-name>
  <filter-class>com.java3z.examples.ClickstreamFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>clickstreamFilter</filter-name>
  <url-pattern>*.jsp</url-pattern>
</filter-mapping>

<filter-mapping>
  <filter-name>clickstreamFilter</filter-name>
  <url-pattern>*.html</url-pattern>
</filter-mapping>

<listener>
  <listener-class>com.java3z.examples.ClickstreamLogger</listener-class>
</listener>
<!-- END CLICKSTREAM LOGGER -->

</web-app>
       这注册了ClickstreamFilter并设置其处理*.jsp和*.html来的请求。这也将ClickstreamLogger注册为一个监听器以在应用事件发生时接受他们。

二、既是ServletContextListener又是 HttpSessionListener监听器ClickstreamLogger类

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标记属性来标注此过滤器是否已经被当前请求使用(可能会在请求调度中发生)并且忽略所有其他的过滤器行为。



四、保存请求数据的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应用的所有文件。
posted on 2007-09-27 11:35 lk 阅读(358) 评论(0)  编辑  收藏 所属分类: j2ee

只有注册用户登录后才能发表评论。


网站导航: