Servlets - 调试

  • 简述

    测试/调试 servlet 总是很困难。Servlet 往往涉及大量客户端/服务器交互,因此可能会出现错误但难以重现。
    这里有一些提示和建议,可以帮助您进行调试。
  • System.out.println()

    System.out.println() 很容易用作标记来测试某段代码是否正在执行。我们也可以打印出变量值。此外 -
    • 由于 System object 是核心 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,这些日志可以在 <Tomcat-installation-directory>/logs 中找到。
    日志文件确实给出了新出现的错误或问题频率的指示。出于这个原因,最好在通常不会发生的异常的 catch 子句中使用 log() 函数。
  • 使用 JDB 调试器

    您可以使用与调试小程序或应用程序相同的 jdb 命令来调试 servlet。
    为了调试 servlet,我们调试 sun.servlet.http.HttpServer 并仔细观察 HttpServer 执行 servlet 以响应浏览器发出的 HTTP 请求。这与调试小程序的方式非常相似。不同之处在于,对于applet,实际调试的程序是sun.applet.AppletViewer。
    大多数调试器通过自动知道如何调试小程序来隐藏这个细节。在他们对 servlet 做同样的事情之前,您必须通过执行以下操作来帮助您的调试器 -
    • 设置调试器的类路径,以便它可以找到 sun.servlet.http.Http-Server 和关联的类。
    • 设置调试器的类路径,以便它也可以找到您的 servlet 和支持类,通常是 server_root/servlets 和 server_root/classes。
    您通常不希望在类路径中使用 server_root/servlets,因为它会禁用 servlet 重新加载。但是,这种包含对于调试很有用。它允许您的调试器在 HttpServer 中的自定义 servlet 加载器加载 servlet 之前在 servlet 中设置断点。
    设置正确的类路径后,开始调试 sun.servlet.http.HttpServer。您可以在您对调试感兴趣的任何 servlet 中设置断点,然后使用 Web 浏览器向给定 servlet (http://localhost:8080/servlet/ServletToDebug) 的 HttpServer 发出请求。您应该会看到在断点处停止执行。
  • 使用注释

    代码中的注释可以通过多种方式帮助调试过程。可以在调试过程中以多​​种其他方式使用注释。
    Servlet 使用 Java 注释,单行 (// ...) 和多行 (/* ... */) 注释可用于临时删除部分 Java 代码。如果错误消失,请仔细查看您刚刚注释的代码并找出问题所在。
  • 客户端和服务器头

    有时,当 servlet 未按预期运行时,查看原始 HTTP 请求和响应会很有用。如果您熟悉 HTTP 的结构,则可以阅读请求和响应,并确切了解这些标头的具体情况。
  • 重要的调试技巧

    以下是有关 servlet 调试的更多调试技巧列表 -
    • 请记住 server_root/classes 不会重新加载,而 server_root/servlets 可能会重新加载。
    • 要求浏览器显示它正在显示的页面的原始内容。这可以帮助识别格式问题。它通常是“查看”菜单下的一个选项。
    • 确保浏览器没有通过强制完全重新加载页面来缓存先前请求的输出。使用 Netscape Navigator,使用 Shift-Reload;在 Internet Explorer 中使用 Shift-Refresh。
    • 验证您的 servlet 的 init() 方法是否接受 ServletConfig 参数并立即调用 super.init(config)。