Servlet Debugging
Testing/debugging Servlets is always a difficult part of development. Servlets often involve a lot of client/server interaction, and errors may occur that are hard to reproduce.
Here are some tips and suggestions to help you debug.
System.out.println()
System.out.println() is used as a marker to test whether a specific piece of code has been executed. We can also print out variable values. In addition:
- Since the System object is part of the core Java objects, it can be used anywhere without installing any extra classes. This includes Servlets, JSP, RMI, EJB's, ordinary Beans and classes, as well as standalone applications.
- Unlike stopping at breakpoints, writing to System.out does not interfere with the normal execution flow of the application, which makes it especially valuable when timing is critical.
Here is the syntax for using System.out.println():
System.out.println("Debugging message");
All messages generated through the above syntax will be recorded in the Web server log files.
Message Logging
It is a very good idea to use appropriate logging methods to record all debugging, warning, and error messages. It is recommended to uselog4Jto record all messages.
The Servlet API also provides a simple way to output information, using the log() method, as follows:
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ContextLog extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
java.io.IOException {
String par = request.getParameter("par1");
// 调用两个 ServletContext.log 方法
ServletContext context = getServletContext( );
if (par == null || par.equals(""))
// 通过 Throwable 参数记录版本
context.log("No message received:",
new IllegalStateException("Missing parameter"));
else
context.log("Here is the visitor's message: " + par);
response.setContentType("text/html;charset=UTF-8");
java.io.PrintWriter out = response.getWriter( );
String title = "Context Log";
String docType = "<!DOCTYPE html> \n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#F0F0F0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<h2 align=\"center\">Messages sent</h2>\n" +
"</body></html>");
} //doGet
}
ServletContext records its text messages to the Servlet container's log files. For Tomcat, these logs can be found in the <Tomcat-installation-directory>/logs directory.
These log files do give an indication of the frequency of new errors or problems. Because of this, it is recommended to use the log() function in catch clauses for exceptions that do not normally occur.
Using JDB Debugger
You can use the jdb command for debugging applets or applications to debug Servlets.
To debug a Servlet, we can debug sun.servlet.http.HttpServer, and then regard it as HttpServer executing the Servlet to respond to browser HTTP requests. This is very similar to debugging applets. The difference from debugging an applet is that the actual program being debugged is sun.applet.AppletViewer.
Most debuggers automatically hide the details of how to debug applets. Similarly, for servlets, you must help the debugger do the following:
- Set your debugger's classpath so that it can find sun.servlet.http.HttpServer and related classes.
- Set your debugger's classpath so that it can find your servlet and supporting classes, usually in server_root/servlets and server_root/classes.
You usually do not want server_root/servlets in your classpath, because it disables servlet reloading. But this inclusion rule is very useful for debugging. It allows your debugger to set breakpoints in the Servlet before the custom Servlet loader in HttpServer loads the Servlet.
If you have set the correct classpath, you can start debugging sun.servlet.http.HttpServer. You can set breakpoints in the Servlet code you want to debug, and then use a Web browser to make a request to HttpServer with the given Servlet (http://localhost:8080/servlet/ServletToDebug). You will see the program stop at the breakpoint.
Using Comments
Comments in code help with debugging in various ways. Comments can be used in many other ways during the debugging process.
This Servlet uses Java comments, and single-line comments (//...), multi-line comments (/* ...*/) can be used to temporarily remove parts of Java code. If the bug disappears, carefully look at the code you just commented out and find out the problem.
Client and Server Header Information
Sometimes, when a Servlet is not behaving as expected, it is very useful to look at the raw HTTP request and response. If you are familiar with the HTTP structure, you can read the request and response to see exactly what these headers are.
Important Debugging Tips
Here are some Servlet debugging tips:
- Note that server_root/classes will not be reloaded, while server_root/servlets may be.
- Ask the browser to display the raw content of the page it is showing. This helps identify formatting issues. It is usually an option under the "View" menu.
- Make sure the browser has not cached the previous request's output by forcing a full page reload. In Netscape Navigator, use Shift-Reload; in Internet Explorer, use Shift-Refresh.
- Make sure the servlet's init() method accepts a ServletConfig parameter and calls super.init(config).