# JSP 調試
要測試/調試一個JSP或servlet程序總是那么的難。JSP和Servlets程序趨向于牽涉到大量客戶端/服務器之間的交互,這很有可能會產生錯誤,并且很難重現出錯的環境。
接下來將會給出一些小技巧和小建議,來幫助您調試程序。
## 使用System.out.println()
System.out.println()可以很方便地標記一段代碼是否被執行。當然,我們也可以打印出各種各樣的值。此外:
* 自從System對象成為Java核心對象后,它便可以使用在任何地方而不用引入額外的類。使用范圍包括Servlets,JSP,RMI,EJB's,Beans,類和獨立應用。
* 與在斷點處停止運行相比,用System.out進行輸出不會對應用程序的運行流程造成重大的影響,這個特點在定時機制非常重要的應用程序中就顯得非常有用了。
接下來給出了使用System.out.println()的語法:
```
System.out.println("Debugging message");
```
這是一個使用System.out.print()的簡單例子:
```
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>System.out.println</title></head>
<body>
<c:forEach var="counter" begin="1" end="10" step="1" >
<c:out value="${counter-5}"/></br>
<% System.out.println( "counter= " +
pageContext.findAttribute("counter") ); %>
</c:forEach>
</body>
</html>
```
現在,如果運行上面的例子的話,它將會產生如下的結果:
```
-4
-3
-2
-1
0
1
2
3
4
5
```
如果使用的是Tomcat服務器,您就能夠在logs目錄下的stdout.log文件中發現多出了如下內容:
```
counter=1
counter=2
counter=3
counter=4
counter=5
counter=6
counter=7
counter=8
counter=9
counter=10
```
使用這種方法可以將變量和其它的信息輸出至系統日志中,用來分析并找出造成問題的深層次原因。
## 使用JDB Logger
J2SE日志框架可為任何運行在JVM中的類提供日志記錄服務。因此我們可以利用這個框架來記錄任何信息。
讓我們來重寫以上代碼,使用JDK中的 logger API:
```
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page import="java.util.logging.Logger" %>
<html>
<head><title>Logger.info</title></head>
<body>
<% Logger logger=Logger.getLogger(this.getClass().getName());%>
<c:forEach var="counter" begin="1" end="10" step="1" >
<c:set var="myCount" value="${counter-5}" />
<c:out value="${myCount}"/></br>
<% String message = "counter="
+ pageContext.findAttribute("counter")
+ " myCount="
+ pageContext.findAttribute("myCount");
logger.info( message );
%>
</c:forEach>
</body>
</html>
```
它的運行結果與先前的類似,但是,它可以獲得額外的信息輸出至stdout.log文件中。在這我們使用了logger中的info方法。下面我們給出stdout.log文件中的一個快照:
```
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=1 myCount=-4
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=2 myCount=-3
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=3 myCount=-2
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=4 myCount=-1
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=5 myCount=0
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=6 myCount=1
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=7 myCount=2
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=8 myCount=3
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=9 myCount=4
24-Sep-2013 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter=10 myCount=5
```
消息可以使用各種優先級發送,通過使用sever(),warning(),info(),config(),fine(),finer(),finest()方法。finest()方法用來記錄最好的信息,而sever()方法用來記錄最嚴重的信息。
使用Log4J 框架來將消息記錄在不同的文件中,這些消息基于嚴重程度和重要性來進行分類。
## 調試工具
NetBeans是樹形結構,是開源的Java綜合開發環境,支持開發獨立的Java應用程序和網絡應用程序,同時也支持JSP調試。
NetBeans支持如下幾個基本的調試功能:
* 斷點
* 單步跟蹤
* 觀察點
詳細的信息可以查看NetBeans使用手冊。
## 使用JDB Debugger
可以在JSP和servlets中使用jdb命令來進行調試,就像調試普通的應用程序一樣。
通常,我們直接調試sun.servlet.http.HttpServer 對象來查看HttpServer在響應HTTP請求時執行JSP/Servlets的情況。這與調試applets非常相似。不同之處在于,applets程序實際調試的是sun.applet.AppletViewer。
大部分調試器在調試applets時都能夠自動忽略掉一些細節,因為它知道如何調試applets。如果想要將調試對象轉移到JSP身上,就需要做好以下兩點:
* 設置調試器的classpath,讓它能夠找到sun.servlet.http.Http-Server? 和相關的類。
* 設置調試器的classpath,讓它能夠找到您的JSP文件和相關的類。
設置好classpath后,開始調試sun.servlet.http.Http-Server 。您可以在JSP文件的任意地方設置斷點,只要你喜歡,然后使用瀏覽器發送一個請求給服務器就應該可以看見程序停在了斷點處。
## 使用注釋
程序中的注釋在很多方面都對程序的調試起到一定的幫助作用。注釋可以用在調試程序的很多方面中。
JSP使用Java注釋。如果一個BUG消失了,就請仔細查看您剛注釋過的代碼,通常都能找出原因。
## 客戶端和服務器的頭模塊
有時候,當JSP沒有按照預定的方式運行時,查看未加工的HTTP請求和響應也是很有用的。如果對HTTP的結構很熟悉的話,您可以直接觀察request和response然后看看這些頭模塊到底怎么了。
## 重要調試技巧
這里我們再透露兩個調試JSP的小技巧:
* 使用瀏覽器顯示原始的頁面內容,用來區分是否是格式問題。這個選項通常在View菜單下。
* 確保瀏覽器在強制重新載入頁面時沒有捕獲先前的request輸出。若使用的是Netscape Navigator瀏覽器,則用Shift-Reload;若使用的是IE瀏覽器,則用Shift-Refresh。
- Java 基礎
- Java 簡介
- Java開發環境配置
- Java基礎語法
- Java對象和類
- Java基本數據類型
- Java變量類型
- Java修飾符
- Java運算符
- Java循環結構 - for, while 及 do...while
- Java分支結構 - if...else/switch
- Java Number類
- Java Character類
- Java String類
- Java StringBuffer和StringBuilder類
- Java 數組
- Java 日期時間
- Java正則表達式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 異常處理
- Java 面向對象
- Java 繼承
- Java 重寫(Override)與重載(Overload)
- Java 多態
- Java 抽象類
- Java 接口
- Java 包(package)
- Java 高級教程
- Java 數據結構
- Java Enumeration接口
- Java Bitset類
- Java Vector 類
- Java Stack 類
- Java Dictionary 類
- Java Hashtable 接口
- Java Properties 接口
- Java 集合框架
- Java 泛型
- Java序列化
- Java 網絡編程
- Java 發送郵件
- Java 多線程編程
- Java Applet基礎
- Java 文檔注釋
- Servlet 教程
- Servlet 簡介
- Servlet 環境設置
- Servlet 生命周期
- Servlet 實例
- Servlet 表單數據
- Servlet 客戶端 HTTP 請求
- Servlet 服務器 HTTP 響應
- Servlet HTTP 狀態碼
- Servlet 編寫過濾器
- Servlet 異常處理
- Servlet Cookies 處理
- Servlet Session 跟蹤
- Servlet 數據庫訪問
- Servlet 文件上傳
- Servlet 處理日期
- Servlet 網頁重定向
- Servlet 點擊計數器
- Servlet 自動刷新頁面
- Servlet 發送電子郵件
- Servlet 包
- Servlet 調試
- Servlet 國際化
- JSP 基礎
- JSP 簡介
- JSP 開發環境搭建
- JSP 結構
- JSP 生命周期
- JSP 語法
- JSP 指令
- JSP 動作元素
- JSP 動作元素
- JSP 隱含對象
- JSP 客戶端請求
- JSP 服務器響應
- JSP HTTP 狀態碼
- JSP 表單處理
- JSP 過濾器
- JSP Cookies 處理
- JSP Session
- JSP 文件上傳
- JSP 日期處理
- JSP 頁面重定向
- JSP 點擊量統計
- JSP 自動刷新
- JSP 發送郵件
- JSP 高級教程
- JSP 標準標簽庫(JSTL)
- JSP 連接數據庫
- JSP XML 數據處理
- JSP JavaBean
- JSP 自定義標簽
- JSP 表達式語言
- JSP 異常處理
- JSP 調試
- JSP 國際化
- 免責聲明