Servlets - 调试 debug
测试/调试servlet总是很困难。 Servlet往往涉及大量的客户端/服务器交互,使得错误可能但很难重现。
以下是一些可能有助于您进行调试的提示和建议。
System.out.println()
System.out.println()很容易用作标记来测试某段代码是否正在执行。 我们也可以打印出变量值。 另外 -
由于System对象是核心Java对象的一部分,因此可以在任何地方使用它,而无需安装任何额外的类。 这包括Servlet,JSP,RMI,EJB,普通Bean和类以及独立应用程序。
在断点处停止技术会停止正常执行,因此需要更多时间。 而写入System.out并不会干扰应用程序的正常执行流程,这使得在时序至关重要时非常有价值。
以下是使用System.out.println()的语法 -
System.out.println("Debugging message");
上述语法生成的所有消息都将记录在Web服务器日志文件中。
消息记录
使用正确的日志记录方法使用标准日志记录方法记录所有调试,警告和错误消息始终是个好主意。 我使用log4J来记录所有消息。
Servlet API还提供了一种使用log()方法输出信息的简单方法,如下所示 -
// 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,这些日志可以在
日志文件确实指示了新出现的错误或问题的频率。 因此,最好在异常的catch子句中使用log()函数,这通常不会发生。
使用JDB调试器
您可以使用用于调试applet或应用程序的相同jdb命令来调试servlet。
为了调试servlet,我们调试sun.servlet.http.HttpServer并仔细观察HttpServer执行servlet以响应从浏览器发出的HTTP请求。 这与applet的调试方式非常相似。 不同之处在于,对于applet,正在调试的实际程序是sun.applet.AppletViewer。
大多数调试器通过自动知道如何调试applet来隐藏这个细节。 在他们对servlet执行相同操作之前,您必须通过执行以下操作来帮助您的调试器 -
设置调试器的类路径,以便它可以找到sun.servlet.http.Http-Server和相关的类。
设置调试器的类路径,以便它也可以找到您的servlet和支持类,通常是server_root/servlets和server_root/classes。
您通常不希望在类路径中使用server_root/servlet,因为它会禁用servlet重新加载。 但是,这种包含对于调试很有用。 它允许调试器在HttpServer中的自定义servlet加载器加载servlet之前在servlet中设置断点。
设置正确的类路径后,开始调试sun.servlet.http.HttpServer。 您可以在任何您想调试的servlet中设置断点,然后使用Web浏览器向HttpServer请求给定的servlet(http:// localhost:8080/servlet/ServletToDebug)。 您应该看到在断点处停止执行。
使用评论
代码中的注释可以通过各种方式帮助调试过程。 在调试过程中,可以通过许多其他方式使用注释。
Servlet使用Java注释,单行(// ...)和多行(/ * ... * /)注释可用于临时删除部分Java代码。 如果错误消失,请仔细查看您刚评论的代码并找出问题所在。
客户端和服务器标头
有时,当servlet的行为不符合预期时,查看原始HTTP请求和响应很有用。 如果您熟悉HTTP的结构,则可以阅读请求和响应,并确切了解这些标头的确切内容。
重要的调试技巧
以下列出了一些有关servlet调试的更多调试技巧 -
请记住,server_root/classes不会重新加载,而server_root/servlets可能会重新加载。
请求浏览器显示其正在显示的页面的原始内容。 这有助于识别格式问题。 它通常是“视图”菜单下的一个选项。
通过强制完全重新加载页面,确保浏览器不缓存先前请求的输出。 使用Netscape Navigator,使用Shift-Reload; 使用Internet-Refresh使用Shift-Refresh。
验证servlet的init()方法是否采用ServletConfig参数并立即调用super.init(config)。