調(diào)試

2018-11-12 18:03 更新

調(diào)試

測(cè)試/調(diào)試 servlet 始終是困難的。Servlets 往往涉及大量的客戶端/服務(wù)器交互,可能會(huì)出現(xiàn)錯(cuò)誤但是又難以重現(xiàn)。

這里有一些提示和建議,可以幫助你調(diào)試。

System.out.println()

System.out.println() 作為一個(gè)標(biāo)記用來(lái)測(cè)試某一代碼片段是否被執(zhí)行,使用方法非常簡(jiǎn)單。我們也可以輸出變量值。另外:

  • 由于 System 對(duì)象是核心 Java 對(duì)象的一部分,它可以用于任何不需要安裝任何額外類(lèi)的地方。這包括 Servlets、JSP、RMI、EJB's、普通的 Beans 和類(lèi),以及獨(dú)立的應(yīng)用程序。

  • 與在斷點(diǎn)處停止相比,寫(xiě)入 System.out 不會(huì)對(duì)應(yīng)用程序的正常執(zhí)行流程有太多干擾,這使得它在時(shí)序重要的時(shí)候顯得非常有價(jià)值。

以下使用 System.out.println() 的語(yǔ)法:

System.out.println("Debugging message");

通過(guò)上述語(yǔ)法生成的所有消息將被記錄在 web 服務(wù)器的日志文件中。

消息記錄

利用標(biāo)準(zhǔn)日志記錄方法,使用適當(dāng)?shù)娜罩居涗浄椒▉?lái)記錄所有調(diào)試、警告和錯(cuò)誤消息是非常好的想法,我使用的是log4J 來(lái)記錄所有的消息。

Servlet API 還提供了一個(gè)簡(jiǎn)單的輸出信息的方式,使用 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 目錄中找到。

這些日志文件確實(shí)為新出現(xiàn)的錯(cuò)誤或問(wèn)題的頻率給出了指示。正因?yàn)槿绱?,在通常不?huì)出現(xiàn)的異常 catch 子句中使用 log() 函數(shù)是很好的。

使用 JDB 調(diào)試器

你可以使用調(diào)試 applet 或應(yīng)用程序的相同的 jdb 命令來(lái)調(diào)試 servlet。

為了調(diào)試一個(gè) servlet,我們可以調(diào)試 sun.servlet.http.HttpServer,然后把它看成是 HttpServer 執(zhí)行 servlet 來(lái)響應(yīng)來(lái)自瀏覽器端的 HTTP 請(qǐng)求。這與調(diào)試 applet 小程序的方式非常相似。與調(diào)試 applet 不同的是,被調(diào)試的實(shí)際程序是 sun.applet.AppletViewer。

大多數(shù)調(diào)試器會(huì)自動(dòng)隱藏了解如何調(diào)試 applet 的細(xì)節(jié)。直到他們?yōu)?servlet 做同樣的事情,你必須做以下操作來(lái)幫助你的調(diào)試器:

  • 設(shè)置你的調(diào)試器的類(lèi)路徑,以便它可以找到 sun.servlet.http.Http-Server 和相關(guān)的類(lèi)。

  • 設(shè)置你的調(diào)試器的類(lèi)路徑,以便它可以找到你的 servlet 和支持的類(lèi),通常是在 server_root/servlets 和 server_root/classes 中。

你通常不會(huì)希望 server_root/servlets 在你的 classpath 中,因?yàn)樗鼤?huì)禁用 servlet 的重載。然而這種包含對(duì)于調(diào)試是有用的。在 HttpServer 中的自定義的 servlet 加載器加載 servlet 之前,它允許你的調(diào)試器在 servlet 中設(shè)置斷點(diǎn)。

一旦你設(shè)置了正確的類(lèi)路徑,就可以開(kāi)始調(diào)試 sun.servlet.http.HttpServer。你可以在任何你想要調(diào)試的 servlet 中設(shè)置斷點(diǎn),然后使用 web 瀏覽器為給定的 servlet(http://localhost:8080/servlet/ServletToDebug) 向 HttpServer 發(fā)出請(qǐng)求。你會(huì)看到程序執(zhí)行到你設(shè)置的斷點(diǎn)處停止。

使用注釋

代碼中的注釋有助于以各種方式調(diào)試程序。注釋可用于調(diào)試過(guò)程中的許多其他方式中。

Servlet 使用 Java 注釋?zhuān)瑔涡凶⑨專(zhuān)?/...)和多行注釋?zhuān)? .../)可用于暫時(shí)移除部分 Java 代碼。如果 bug 消失,仔細(xì)看看你之前注釋的代碼并找出問(wèn)題所在。

客戶端和服務(wù)器端頭信息

有時(shí),當(dāng)一個(gè) servlet 并沒(méi)有像預(yù)期那樣工作時(shí),查看原始的 HTTP 請(qǐng)求和響應(yīng)是非常有用的。如果你對(duì) HTTP 結(jié)構(gòu)很熟悉,你可以閱讀請(qǐng)求和響應(yīng),看看這些頭信息中究竟是什么。

重要的調(diào)試技巧

這里是 servlet 調(diào)試中的一些調(diào)試技巧列表:

  • 請(qǐng)注意 server _ root/classes 不會(huì)重載,而 server_root/servlets 可能會(huì)。

  • 要求瀏覽器顯示它所顯示的頁(yè)面的原始內(nèi)容。這有助于識(shí)別格式的問(wèn)題。它通常是視圖菜單下的一個(gè)選項(xiàng)。

  • 通過(guò)強(qiáng)制執(zhí)行完全重載頁(yè)面,來(lái)確保瀏覽器還沒(méi)有緩存前一個(gè)請(qǐng)求的輸出。在 Netscape Navigator 中,使用 Shift-Reload;在 IE 瀏覽器中,請(qǐng)使用 Shift-Refresh。

  • 確認(rèn) servlet 的 init() 方法接受一個(gè) ServletConfig 參數(shù)并立即調(diào)用 super.init(config)。
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)