測(cè)試/調(diào)試 servlet 始終是困難的。Servlets 往往涉及大量的客戶端/服務(wù)器交互,可能會(huì)出現(xiàn)錯(cuò)誤但是又難以重現(xiàn)。
這里有一些提示和建議,可以幫助你調(diào)試。
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)用程序。
以下使用 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ù)是很好的。
你可以使用調(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)。
你通常不會(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)題所在。
有時(shí),當(dāng)一個(gè) servlet 并沒(méi)有像預(yù)期那樣工作時(shí),查看原始的 HTTP 請(qǐng)求和響應(yīng)是非常有用的。如果你對(duì) HTTP 結(jié)構(gòu)很熟悉,你可以閱讀請(qǐng)求和響應(yīng),看看這些頭信息中究竟是什么。
這里是 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。
更多建議: