Servlets 简明教程
Servlets - Debugging
测试/调试 servlet 总是一件困难的事情。servlet 往往涉及大量客户端/服务器交互,因此错误可能很频繁,但难以重现。
It is always difficult to testing/debugging a servlets. Servlets tend to involve a large amount of client/server interaction, making errors likely but hard to reproduce.
以下是一些技巧和建议,可以帮助您进行调试。
Here are a few hints and suggestions that may aid you in your debugging.
System.out.println()
System.out.println() 易于用作标记,以测试程序的某个部分是否正在执行。我们还可以打印出变量值。此外 −
System.out.println() is easy to use as a marker to test whether a certain piece of code is being executed or not. We can print out variable values as well. Additionally −
-
Since the System object is part of the core Java objects, it can be used everywhere without the need to install any extra classes. This includes Servlets, JSP, RMI, EJB’s, ordinary Beans and classes, and standalone applications.
-
Stopping at breakpoints technique stops the normal execution hence takes more time. Whereas writing to System.out doesn’t interfere much with the normal execution flow of the application, which makes it very valuable when timing is crucial.
以下是如何使用 System.out.println() 的语法 −
Following is the syntax to use System.out.println() −
System.out.println("Debugging message");
通过上述语法生成的所有消息都将记录在 Web 服务器日志文件中。
All the messages generated by above syntax would be logged in web server log file.
Message Logging
使用标准日志方法记录所有调试、警告和错误消息始终是一个好主意。我使用 log4J 记录所有消息。
It is always great idea to use proper logging method to log all the debug, warning and error messages using a standard logging method. I use log4J to log all the messages.
Servlet API 还提供了一种通过使用 log() 方法输出信息更简单的方法,如下所示 −
The Servlet API also provides a simple way of outputting information by using the log() method as follows −
// Import required java libraries
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");
//Call the two ServletContext.log methods
ServletContext context = getServletContext( );
if (par == null || par.equals(""))
//log version with Throwable parameter
context.log("No message received:", new IllegalStateException("Missing parameter"));
else
context.log("Here is the visitor's message: " + par);
response.setContentType("text/html");
java.io.PrintWriter out = response.getWriter( );
String title = "Context Log";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">\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 将其文本消息记录到 servlet 容器的日志文件中。在 Tomcat 中,这些日志位于 <Tomcat 安装目录>/logs。
The ServletContext logs its text messages to the servlet container’s log file. With Tomcat these logs are found in <Tomcat-installation-directory>/logs.
日志文件确实提示了新出现的错误或问题的发生频率。因此,在通常不应该发生的异常的 catch 子句中使用 log() 函数效果不错。
The log files do give an indication of new emerging bugs or the frequency of problems. For that reason it’s good to use the log() function in the catch clause of exceptions which should normally not occur.
Using JDB Debugger
您可以使用与用于调试 applet 或应用程序相同的 jdb 命令来调试 serlet。
You can debug servlets with the same jdb commands you use to debug an applet or an application.
要调试 serlet,我们调试 sun.servlet.http.HttpServer,并在 HttpServer 响应来自浏览器 HTTP 请求执行 servlet 时仔细观察行为。这与调试小程序非常相似。不同之处在于,对于小程序,要调试的实际程序是 sun.applet.AppletViewer。
To debug a servlet, we debug sun.servlet.http.HttpServer and carefully watch as HttpServer executes servlets in response to HTTP requests made from browser. This is very similar to how applets are debugged. The difference is that with applets, the actual program being debugged is sun.applet.AppletViewer.
大多数调试器通过自动了解如何调试小程序隐藏此详细信息。直到它们对 servlet 执行相同的操作,您才必须通过执行以下操作帮助您的调试器 −
Most debuggers hide this detail by automatically knowing how to debug applets. Until they do the same for servlets, you have to help your debugger by doing the following −
-
Set your debugger’s classpath so that it can find sun.servlet.http.Http-Server and associated classes.
-
Set your debugger’s classpath so that it can also find your servlets and support classes, typically server_root/servlets and server_root/classes.
您通常不希望将 server_root/servlets 放入类路径,因为它会禁用 servlet 重新加载。但是,此包含项对调试很有用。它允许您的调试器在 HttpServer 中的自定义 servlet 加载器加载 servlet 之前在 servlet 中设置断点。
You normally wouldn’t want server_root/servlets in your classpath because it disables servlet reloading. This inclusion, however, is useful for debugging. It allows your debugger to set breakpoints in a servlet before the custom servlet loader in HttpServer loads the servlet.
设置好正确的类路径后,开始调试 sun.servlet.http.HttpServer。您可以在您想要调试的任何 servlet 中设置断点,然后使用网络浏览器向 HttpServer 发出对给定 servlet 的请求([role="bare"] [role="bare"]http://localhost:8080/servlet/ServletToDebug )。您应该看到执行在您的断点处停止。
Once you have set the proper classpath, start debugging sun.servlet.http.HttpServer. You can set breakpoints in whatever servlet you’re interested in debugging, then use a web browser to make a request to the HttpServer for the given servlet ([role="bare"]http://localhost:8080/servlet/ServletToDebug). You should see execution being stopped at your breakpoints.
Using Comments
代码中的注释可以通过多种方式帮助调试过程。注释可以在调试过程中的许多其他方式中使用。
Comments in your code can help the debugging process in various ways. Comments can be used in lots of other ways in the debugging process.
Servlet 使用 Java 注释,并且可以使用单行(// …)和多行(/* … */)注释来临时删除 Java 代码的部分。如果错误消失了,请仔细查看您刚刚注释的代码并找出问题。
The Servlet uses Java comments and single line (// …) and multiple line (/* … */) comments can be used to temporarily remove parts of your Java code. If the bug disappears, take a closer look at the code you just commented and find out the problem.
Client and Server Headers
有时,当 servlet 未按预期运行时,查看原始 HTTP 请求和响应非常有用。如果您熟悉 HTTP 的结构,您可以读取请求和响应,并确切地了解那些标头正在做什么。
Sometimes when a servlet doesn’t behave as expected, it’s useful to look at the raw HTTP request and response. If you’re familiar with the structure of HTTP, you can read the request and response and see exactly what exactly is going with those headers.
Important Debugging Tips
此处列出了一些有关 servlet 调试的其他调试提示 −
Here is a list of some more debugging tips on servlet debugging −
-
Remember that server_root/classes doesn’t reload and that server_root/servlets probably does.
-
Ask a browser to show the raw content of the page it is displaying. This can help identify formatting problems. It’s usually an option under the View menu.
-
Make sure the browser isn’t caching a previous request’s output by forcing a full reload of the page. With Netscape Navigator, use Shift-Reload; with Internet Explorer use Shift-Refresh.
-
Verify that your servlet’s init() method takes a ServletConfig parameter and calls super.init(config) right away.