Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 5
The following web.xml deployment-descriptor snippet wires everything together:
<
filter>
<filter-name>clickstreamFilter</filter-name>
<filter-class>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>ClickstreamLogger</listener-class>
</listener>This registers the ClickstreamFilter and sets it up to handle *.jsp and *.html requests. This also registers the ClickstreamLogger as a listener to receive application events when they occur.
The two JSP pages pull the clickstream data from the session and context objects and use an HTML interface to display the current status. The following clickstreams.jspfile shows the overall summary:
<
%@ page import="java.util.*" %>
<%@ page import="Clickstream" %>
<%
Map clickstreams = (Map)application.getAttribute("clickstreams");
String showbots = "false";
if (request.getParameter("showbots") != null) {
if (request.getParameter("showbots").equals("true"))
showbots = "true";
else if (request.getParameter("showbots").equals("both"))
showbots = "both";
}
%>
<font face="Verdana" size="-1">
<h1>All Clickstreams</h1>
<a href="clickstreams.jsp?showbots=false">No Bots</a> |
<a href="clickstreams.jsp?showbots=true">All Bots</a> |
<a href="clickstreams.jsp?showbots=both">Both</a> <p>
<% if (clickstreams.keySet().size() == 0) { %>
No clickstreams in progress
<% } %>
<%
Iterator it = clickstreams.keySet().iterator();
int count = 0;
while (it.hasNext()) {
String key = (String)it.next();
Clickstream stream = (Clickstream)clickstreams.get(key);
if (showbots.equals("false") && stream.isBot()) {
continue;
}
else if (showbots.equals("true") && !stream.isBot()) {
continue;
}
count++;
try {
%>
<%= count %>.
<a href="viewstream.jsp?sid=<%= key %>"><b>
<%= (stream.getHostname() != null && !stream.getHostname().equals("") ?
stream.getHostname() : "Stream") %>
</b></a> <font size="-1">[<%= stream.getStream().size() %> reqs]</font><br>
<%
}
catch (Exception e) {
%>
An error occurred - <%= e %><br>
<%
}
}
%>The package is fairly easy to download and install from the OpenSymphony Website. Place and compile the Java files in WEB-INF/classes, put the JSP files in the Web application root, and modify the web.xml file as instructed. To save you the hassle of even this much work, you can find a prepackaged WAR file available at http://www.javaworld.com/jw-06-2001/Filters/clickstream.war.
For the filter to work on Tomcat 4.0 beta 5, I found I had to make some slight portability modifications. The changes I made show some common pitfalls in servlet and filter portability, so I'll list them here:
<%@ page import="Clickstream" %>. In Java you don't have to import classes within your own package, so on servers where JSPs compile into the default package,
you don't need an import line like this. But on servers like Tomcat where JSPs compile into a custom package, you have to
explicitly import classes in the default package.
<listener> element in the web.xmlfile after the <filter>and <filter-mapping> elements, as required by the deployment descriptor DTD. Not all servers require elements to be in the proper order, but Tomcat
does.
web.xml mapping from /*.htmland /*.jsp to the more correct *.htmland *.jsp. Some servers are forgiving of the leading slash, but Tomcat rigidly enforces the rule that prohibits that slash.
ClickstreamFilter class up to the latest lifecycle API, changing setFilterConfig()to the newer init() and destroy()methods.
The downloadable WAR contains all these modifications and should run out-of-the-box across servers, although I haven't tested it widely.