工具提示中的变量计算
当调试会话处于活动状态时,通过悬停在变量上,可以直接在 Java 编辑器中计算该变量。如果变量在当前上下文中处于活动状态,则会在工具提示中显示该变量的值。
例如,当 DebugExample 应用程序在 Web 浏览器中以调试模式运行(如上所述)时,在文本字段中输入 32,然后单击 "Convert"。当返回到 IDE 并将鼠标悬停在 tc 变量上时,您会看到如图 7 所示的工具提示。
图 7:计算变量 |
当程序包括同名的不同变量时,Java 编辑器将基于当前上下文来显示值。
编程时考虑可维护性
仅当具有要检查的局部变量时,才能检查局部变量。例如,假定可以将 button1_action() 方法的核心部分精简为以下单个表达式语句:
| 代码样例 2:精简的按钮操作方法 |
public String button1_action() {
getStaticText1().setValue(Double.toString((((new
Double((String)getTextField1().getValue())).doubleValue( )-32.0) /
1.8)));
return null;
}
|
以这种方式表示时,方法没有局部变量,并且“局部变量”窗口不会显示有关程序运行方式的任何信息。此种精简并不是所希望的,因为它使得故障排除和维护更为困难。
另一种方法是将 Java 断言放置到程序中。assert 关键字计算布尔表达式,如果计算结果为 false,则允许您执行诸如输出错误消息之类的操作。使用断言,您可以轻松地测试程序所需的前置条件。
监视点
通过设置监视点可以监视表达式的值。例如:
- 确保已经在
button1_action() 方法的结尾附近(例如,在 return null; 语句中)设置一个断点。
- 在 Page1.java 的 Java 编辑器中,在
button1_action() 方法中选中以下表达式:
(tf - 32.0) / 1.8
- 单击鼠标右键,然后从上下文菜单中选择“新建监视”(Ctrl-Shift-W)。
图 8:设置监视点 |
- 将出现一个对话框,您可以在该对话框中编辑监视点表达式。在本示例中,不编辑表达式。在对话框中单击“确定”。
- 在 Web 浏览器中,输入华氏温度值
212。当程序在断点处暂停时,在调试器窗口的“监视”标签中查看监视点。监视点报告表达式的当前值。先不要继续执行。
图 9:监视表达式 |
- 在“监视”窗口中单击“值”字段,并尝试将值从
100.0 更改为 50.0。如果键入新值并按 Enter 键,将显示一条消息,指出您不能设置表达式的值。
但是,如果已经在变量(而不是表达式)上设置监视点,则在程序暂停时您将能够更改变量的值,就像在“变量”窗口中那样。
- 在 Java 编辑器中,从同一代码行中仅选择变量
tc:
double tc = (tf - 32.0)/1.8
- 单击鼠标右键,然后从上下文菜单中选择“新建监视”。
另一个监视点出现在“监视”窗口中,而且立即显示变量的值。
- 单击
tc 的“值”字段右侧的省略号按钮 (..),将值更改为 50,然后单击“确定”。
这一次 IDE 允许您更改值。
图 10:更改变量的值 |
在“监视”窗口中,将值 50.0 赋予了变量 tc,尽管确定它的计算结果是 100.0。
- 监视点是一种在程序暂停时计算表达式的简便方式。例如,在
button1_action() 方法中的以下表达式上设置监视点:
Double.toString(tc)
确认其值为 "50.0"。
- 按 Alt-F5 组合键继续执行程序。在请求生命周期结束时,监视点值将被替换为消息
>Thread has been resumed<。
验证输入
到目前为止,仅使用数字对应用程序进行了测试。如果在文本字段中输入非数字字符,会出现什么情况呢?正如您可能猜到的,结果将是令人不满意的。要查明将会出现什么情况,请在文本字段中输入字符 a,然后单击 "Convert"。Web 浏览器将通知您出现未处理的异常。
图 11:浏览器窗口中未处理的异常 |
应用程序必须测试输入字符以确保它们是数字字符。IDE 仅为这样的使用情况提供验证器。
现在,将一个“验证器”组件与输入文本字段相关联。
- 选择“运行”>“完成调试器会话”(Shift-F5)。
- 如有必要,请单击“设计”以打开可视设计器。
- 在组件面板的“组件”标签中,从“验证器”类别中选择“双精度范围验证器”,并将其拖动到可视设计器中的“文本字段”组件上,如下图所示。
图 12:在“文本字段”上设置验证器 |
- 单击“运行主项目”工具栏按钮
或按 Ctrl-F5 组合键。
注意:如果应用程序没有部署,请关闭应用程序以前在其中运行的 Web 浏览器窗口,然后再次运行主项目。
- 当应用程序在 Web 浏览器中打开时,输入字符
a,然后单击 "Convert"。验证器通过将消息传递到与输入文本字段关联的“消息”组件来处理异常。“消息”组件将消息显示给用户,如下图所示。
图 13:验证错误消息 |
您需要再检查一项内容:如果输入空字符串,会出现什么情况。不在文本字段中输入任何内容,就单击 "Convert",则会在 Web 浏览器中再次看到异常。可以清楚地看出,验证器组件未解决所有问题。
查看服务器日志
由于空字符串错误会导致 JavaServer Faces 异常,因此可以在 IDE 创建的服务器日志中找到更多信息。要查看该日志,请转到“服务器”窗口,右键单击“部署服务器”,然后选择“查看服务器日志”。
图 14:查看服务器日志 |
日志文件出现在 IDE 的输出窗口中。最新的消息被附加到文件的结尾。类似如下的行对 Java 语言异常进行了说明,该异常是由于 button1_action() 方法中的空字符串而导致的。
Caused by: java.lang.NullPointerException
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:991)
at java.lang.Double.valueOf(Double.java:447)
at java.lang.Double.<init>(Double.java:539)
at debugexample.Page1.button1_action(Page1.java:289)
有关日志文件的更多信息
在 Windows 系统上,日志文件位于以下文件夹中:
installation- directory\SunAppServer8\domains\creator\logs\
在 Windows 系统上,installation-directory 通常为以下路径:
C:\Program Files\Sun\Creator2\
要生成日志文件,可以使用系统的 println() 方法或 IDE 附带的 log() 方法。log() 方法只能与 IDE 的预配置 Bean 文件(它们是 FacesBean 类的扩展)一起使用。println() 方法可以在任何 Java 文件中使用;如果要导入外部 Java 代码,则该方法可能更有用。
下面的示例使用每个方法输出 tfString 变量的值。在 button1_action() 方法中插入了日志记录语句(在声明 tfString 的行后面),如下所示:
| 代码样例 3:日志记录语句 |
// Existing line
String tfString = ((String)getTextField1().getValue());
// Logging Statements
log("tfString logged = " + tfString);
System.out.println("tfString printed = " + tfString);
|
如果生成并运行应用程序,然后转换华氏温度值 32,则会在 server.log 文件中看到类似如下的消息:
[#|2006-01-15T13:25:04.759-0600|INFO|
sun-appserver-pe8.1_02|javax.enterprise.system.container.web|
_ThreadID=21;|WebModule[/DebugExample]tfString logged = 32|#]
[#|2006-01-15T13:25:04.759-0600|INFO|
sun-appserver-pe8.1_02|javax.enterprise.system.stream.out|
_ThreadID=21;| tfString printed = 32|#]
第一行由 log() 方法创建,第二行由 println() 方法创建。服务器日志信息的格式如下:
[#<Date-Time Identifier> | <Severity Level> |
<Server Identifier> | <Package Identifier> |
<Thread Identifier> | <Logged Information> | #]
设置异常断点
浏览器异常消息和日志条目为您提供了足够的信息,以便使您知道应用程序处理文本字段中空字符串的能力出现了问题。通过设置异常断点,可以从 IDE 调试器了解更多信息。
- 在 IDE 中,按 F5 键启动调试器会话。
- 选择“视图”>“调试”>“断点”以查看“断点”窗口。
- 在“断点”窗口中单击鼠标右键,然后从上下文菜单中选择“新建断点”。将打开“新建断点”对话框。
通过查看原始的 Web 浏览器异常消息中的以下 Caused by: 行,可以知道在何处查找错误:
Caused by: java.lang.NullPointerException
- 在“新建断点”对话框中,输入以下信息:
断点类型:异常
包名:java.lang
异常类名:NullPointerException
停止条件:捕捉到或未捕捉到
您的对话框应如下图所示:
图 15:设置异常断点 |
- 单击“确定”。新断点将出现在“断点”窗口中。
- 在 Web 浏览器中,确保文本字段为空,然后单击 "Convert"。IDE 将在遇到异常时暂停执行。
图 16:在异常断点处暂停执行 |
如果在其中出现异常的类的源代码可用,将显示源文件,而且突出显示出现异常的行。在这种情况下,源代码不可用,因此 Java 编辑器突出显示 Page1.java 中导致异常的行。突出显示的行试图将输入字符串转换为 Double 对象。
此信息确认您已经知道的所有内容,并暗示您必须以某种方式测试输入以确保它不为空。
- 按 Shift-F5 组合键结束调试会话。现在,您将更正错误。
进行修复
可以编写一段代码来测试输入字符串,以确保它不为空。但是,IDE 提供了一种验证是否存在输入字符串的简单方法:在“文本字段”组件上设置一个属性。
- 在 Java 编辑器上面的工具栏中,单击“设计”以显示可视设计器。
- 选择“文本字段”组件。
- 在“文本字段”组件的“属性”窗口中,选中
required 属性的复选框。
图 17:设置 Required 属性 |
- 通过按 Ctrl-F5 组合键部署并运行程序。
- 应用程序在 Web 浏览器中打开时,单击 "Convert",而不在文本字段中输入任何内容。您将会看到错误消息,而不是以前的异常。
- 输入其他值(包括文本字符串),以确保应用程序正确处理文本字段中的所有条目。请注意,您可以转换以科学计数法表示的值,如
-123.4e6。另请注意,文本字段忽略前导空格和后续空格,因为缺省情况下设置了“行为”> "trim" 属性(请参见图 17)。
关于调用栈
调试器允许您通过调用栈来控制程序的执行。调用栈(有时称为调用链)是显示已经调用但尚未返回的方法调用顺序的列表。此列表在顶部显示当前的方法调用,在下面依次显示父调用。
暂停程序时,可以检查调用栈,激活一个调用,以及从栈中弹出调用(更改程序执行,以便使要执行的下一条语句是在之前栈上发出的调用之一)。这些选项可以从“运行”>“栈”菜单进行访问。
查看调用栈如何工作:
- 如有必要,请在左侧空白处单击,确保在
button1_action() 方法中的 return null; 语句处设置了断点。语句应该如下所示:
图 18:在行上设置的断点 |
- 按 F5 键启动调试会话。将启动调试器,并且将生成和部署应用程序。
- 当 Web 应用程序在浏览器中打开时,在文本字段中键入
32,然后单击 "Convert"。
焦点将返回到 IDE,断点行将变成绿色,指示执行已暂停且断点为当前行。
- 如果“调用栈”窗口尚未显示在 Java 编辑器窗口下面,请选择“视图”>“调试”>“调用栈”以显示它。“调用栈”窗口使用粗体字符来表明
Page1.button1_action() 方法是当前调用。如果在调用栈中向下滚动,则会看到一系列系统调用,最终显示对 WorkerThread.run 的原始调用。
图 19:查看调用栈 |
- 在
Page1.button.action 调用的下面,查找第一个 Method.invoke 调用。双击该调用。如果源文件可用,则 IDE 显示源代码行。
图 20:查看调用的源代码 |
Method.invoke 调用的源文件如图 20 所示。请注意,在此情况下源文件标记为只读,因此无法进行编辑。
- 选择“运行”>“栈”>“激活调用者”,并请注意,以前的调用
SecurityUtil$1.run 已变成调用栈中的当前方法。
图 21:激活调用者 |
也可以弹出最上面的调用,这将从调用栈中删除当前方法,并激活上一个调用。通常,从调用栈中弹出一个调用时,不会撤消该调用可能造成的任何影响。例如,如果一个调用打开了一个数据库连接,然后您从栈中弹出了该调用,则该数据库连接仍保持打开。
请注意,在调试器的“调用栈”输出窗口中将看不到由 Java Server Faces 或验证器抛出的异常,因为这些异常会中断 JavaServer Pages 请求的生命周期。同样,如果在可以计算变量的值之前中断生命周期,则看不到局部变量的值。
单步执行代码
暂停程序时,可以单步执行代码行。您将在“运行”菜单上找到以下命令:
- 越过 (F10)。执行一行源代码。如果源代码行包含调用,则执行整个例程而不单步执行单个指令。
- 步入 (F11)。执行一行源代码。如果源代码行包含调用,则会刚好在执行例程的第一条语句之前停止。在对程序状态进行任何更改之前,程序会在 main 例程之后的第一行停止执行。
- 步出 (Shift-F11)。执行一行源代码。如果源代码行是某个例程的一部分,则会执行该例程的其余各行,然后将控制权返回给例程的调用者。
- 运行至光标 (Ctrl-F10)。将当前会话运行至 Java 编辑器中的光标位置,并暂停程序。通常,您将在执行此命令之后执行其中一个单步执行命令。要在程序每次到达该行时都停止程序执行,请设置一个断点。
为了说明这一点,请通过删除所有断点并设置新断点来从头开始:
- 选择“视图”>“调试”>“断点”以查看“断点”窗口。
- 单击鼠标右键,然后从上下文菜单中选择“全部删除”。
图 22:删除所有断点 |
- 在“编辑器”窗口中,如有必要,请单击 Page1 上面的 "Java" 按钮以打开 Java 编辑器,然后在其中设置新断点,方法是在以下语句旁边的左侧空白处单击:
String tfString = ((String)getTextField1().getValue());
- 选择“视图”>“调试”>“局部变量”以查看“局部变量”窗口。
- 如果处于调试会话中,请通过按 Shift-F5 组合键结束它,然后选择“运行”>“调试主项目”以生成并部署程序。
注意:通过单击“运行”菜单,您可以知道自己是否处于调试会话中。如果调试会话正在运行,则调试选项(如“完成调试器会话”)是可用的。
- 在 Web 浏览器中,输入华氏温度值
32,然后单击 "Convert"。在 IDE 中,断点行将以绿色突出显示,表明它是当前行。
- 按 F10 键越过按钮处理程序中的代码。单步执行代码时,当前行以绿色突出显示。请注意,在执行每行时局部变量是如何在“局部变量”窗口中逐个计算的。
图 23:在查看局部变量时越过代码 |
- 通过按 Shift-F5 组合键结束调试器会话。
使用 HTTP 监视器
HTTP 监视器显示应用程序各组件之间的 HTTP 数据流。可以在调试会话中使用 HTTP 监视器,也可以将它与正常部署的应用程序(通过运行主项目生成)一起使用。
HTTP 监视器是通过您所用的应用服务器实现的。要确保启用了 HTTP 监视器,请选中应用服务器属性,如下所示。
- 选择“视图”>“服务器”以使“服务器”窗口可见。
- 右键单击“部署服务器”,然后从上下文菜单中选择“属性”。
- 在必要时启用“常规”>“启用 HTTP 监视器”属性(如图 24 所示),然后关闭该对话框。
图 24:启用 HTML 监视器 |
在后续步骤中,您将看到 HTTP 监视器如何工作。
- 通过单击“运行主项目”工具栏按钮
或者按 Ctrl-F5 组合键,生成并部署应用程序。
- 部署应用程序后,单击 IDE 中的“HTTP 监视器”标签,并展开左面板中的“当前记录”节点。
左面板显示应用程序客户端的所有 HTTP 请求记录。“当前记录”中的条目是当前 IDE 会话的历史记录,在您退出 IDE 之前是可用的。“当前记录”历史记录将始终保留,即使重新启动服务器,但在退出 IDE 时它将丢失。“保存记录”节点中的记录在删除之前将始终保留。
- 展开
GET DebugExample 客户端记录以显示 Page1.jsp 记录。嵌套节点(如 Page1.jsp)是在服务器上进行内部分发的结果。已转发或已包含的这些请求将嵌套在与主请求相对应的节点下面。请注意,并不是所有的服务器都提供此功能。
- 选择左面板中的
Page1.jsp,然后查看右面板中的信息。
图 25:HTML 监视器 |
右面板显示所选请求的会话数据。该数据包括 Cookie 名称/值对、会话数据和 Servlet 上下文。还可以查看 HTTP 头数据和客户端-服务器信息(如客户端协议和 IP 地址)以及服务器平台和主机名。
编辑 HTTP 请求
要编辑 HTTP 记录并重新显示它,请执行以下步骤:
- 在“HTTP 监视器”窗口的右面板中,单击“请求”标签。
- 在运行于 Web 浏览器中的应用程序中,输入
32,然后单击 "Convert"。
- 在“HTTP 监视器”窗口中,展开“当前记录”节点,然后查找 POST 子记录。选择 POST 记录以查看请求信息。
请注意,在应用程序中键入的值 32 现在出现在“参数”区域中,作为 POST 请求的输入 form1:TextField1。
图 26:HTML 监视器 POST 请求 |
- 在 HTTP 监视器的左面板中,右键单击
POST Page1.jsp 节点,然后从上下文菜单中选择“编辑并重新显示”。将打开“编辑并重新显示”对话框。
在“编辑并重新显示”对话框中,可以更改 POST 记录的查询、请求、Cookie、服务器和 HTTP 头信息。
图 27:“编辑并重新显示”对话框 |
- 在“查询”标签上,单击
form1:textField1 行最右侧的省略号 (..),并将值从 32 更改为 212。
- 单击“发送 HTTP 请求”。浏览器中的应用程序接受请求,并将输入的值从
32 更改为 212。
保存 HTTP 请求
要保存 POST 请求以便它在下一个 IDE 会话中仍旧存在,请执行以下步骤。
- 在“HTTP 监视器”窗口的左面板中,选择 POST 请求记录。
- 右键单击 POST 请求记录,然后从上下文菜单中选择“保存”。POST 请求记录将保存在“HTTP 监视器”窗口左面板中的“保存记录”节点下。
- 如果要删除已保存的记录,请右键单击它,然后从上下文菜单中选择“删除”。
小结
在本教程中,您使用了调试器的许多重要功能,其中包括设置断点和监视、查看局部变量、单步执行代码、使用日志文件、查看调用栈以及使用 HTTP 监视器。
另请参见:
此页的最新修改时间:2006 年 1 月 25 日
 |