Managing a web server is a daunting task, especially when you are serving multiple types of dynamic pages. For the City of Tucson, our servers are providing the standard HTML and XHTML, then running on top of that we have PHP and PERL CGI scripts. As an added bonus we're running ColdFusion on a integrated JRun Server, which also serves up JSP pages. And lastly, we have Macromedia's outstanding FLEX application server running in a Tomcat Server (which also serves up JSP pages).
No matter how well you setup your server and design your site and applications, someone somewhere at sometime will have a link to a file that isn't there. So one of the many standard things a web server needs to do is serve up 404 pages, or Page Not Found error pages.
Now the default 404 error that comes with Tomcat is not very useful, it basically tells you that indeed, the page is not there. Most users who encounter a default 404 Page Not Found error simply click the Back button on their web browser and return from whence they came. Now if you design a good site, you should have no dead links of your own, and that means the back button is taking the user AWAY from your site.
Now a good 404 page keeps the user in your site, and lets you, the webmaster, know what happened so you can prevent it from happening again. One good way to do this is to provide a site map or site navigation links on the 404 page, that way the user can simply click on a link within your site and maybe find the page they were searching for. Another good thing to have, especially for larger sites, would be a Search field so they can search your site for what they are looking for.
These things are easy to do, and while these things help the user, how do you identify to yourself when a 404 occurs so you can correct it? The simplest way is an email notice. For this email to be useful, it needs to include parts of the environment such as which page was requested, when the error occurred, and maybe even the browser used. This tutorial covers how to do this with JSP pages, and should work with all JSP servers that support the sun specific sun.net.smtp package, although I've only tested it with Apache Tomcat. If you have a problem using it let me know. If you prefer to use PHP, I have that tutorial here: Custom PHP 404 page.
The Page
The first thing we need to do is to setup our skeleton page and load our packages, which is easy enough:
<%@ page import="sun.net.smtp.SmtpClient, java.io.*, java.util.Date, java.text.SimpleDateFormat" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>404: Page Not Found</title> <meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1" /> </head> <body> <h1>404: Page Not Found</h1> </body> </html>
You can copy and paste this code, it will run as-is and validates as strict XHTML1.1.
Next we want to setup our date format using SimpleDateFormat, instance a client with SmtpClient, set the members and send the message. This page assumes you have your own mail server on your server, however, any SMTP server you have access to will work. Be sure to adjust the first three String variables to match your needs.
<%@ page import="sun.net.smtp.SmtpClient, java.io.*, java.util.Date, java.text.SimpleDateFormat" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>404: Page Not Found</title>
<meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1" />
</head>
<body>
<h1>404: Page Not Found</h1>
<%
String from="web_server@myhost.com";
String to="my_address@myhost.com";
String server="127.0.0.1";
try{
SimpleDateFormat simpleDate = new SimpleDateFormat("EE MMM dd yyyy hh:mm:ss aa zzz");
SmtpClient client = new SmtpClient(server);
client.from(from);
client.to(to);
PrintStream message = client.startMessage();
message.println("To: " + to);
message.println("Subject: 404 Error");
message.println("" + simpleDate.format(new Date()));
message.println();
message.println("" + request.getRemoteAddr() + " tried to load http://" + request.getServerName() + request.getRequestURI());
message.println();
message.println("User Agent = " + request.getHeader("User-Agent"));
message.println();
message.println("" + request.getHeader("Referer"));
message.println();
client.closeServer();
}
catch (IOException e){
System.out.println("Error Sending Email: " + e);
}
%>
</body>
</html>
The resulting email will identify the date and time the request occurred, what IP address requested it, which page they requested, what client they used and any referrer and will look something like this:
Thu Aug 18 2005 03:34:18 PM MST 127.0.0.1 tried to load http://127.0.0.1/404.jsp User Agent = Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6 null
And the last thing you need to do to utilize your custom page is to modify your web.xml, found by default in $CATALINA_HOME/conf/. After the welcome-file-list section add this section and restart Tomcat.
<error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page>

