从Java问世之初,Java程序员就开始使用这种语言的一个内置特性来打印有关程序状态的消息。Java中的System对象提供了两种不同的PrintStream,分别是out和err,可以用于在控制台上打印消息。Out通常映射到标准输出(standard out),err 映射到标准错误输出(standard err)。如果从命令行运行一个应用,那么标准错误输出和标准输出通常都发送到控制台。控制台(console)是一个文本窗口,与图3-2显示的Tomcat 4.1控制台输出类似。许多Web容器不是把消息显示在控制台窗口上,而是捕获输出流,并把输出发送到日志文件;这也是Tomcat 5的默认行为。如果在一个集成开发环境(Integrated Development Environment,IDE)中运行应用,IDE通常会提供一个窗口来显示控制台输出流。我们可以使用这个特性来测量JSP代码。

图3-2 Tomcat 4.1将输出显示在控制台窗口中
在下面的实验中,我们将使用前面打印从–5到5的例子。
实验:用System.out.println()测量代码
这一次要在forEach 循环中增加一条println语句,来显示我们关心的值有何变化:
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>JSP Page</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>
把这个JSP命名为Example3.jsp ,请特别注意以上增加的代码(加阴影)。这行代码是一个scriptlet,每次循环时,它会把计数器的值发送到标准输出。计数器存储为JSP页面上下文(pageContext)中的一个属性,所以必须调用pageContext.findAttribute() 来打印计数器的值。
Web浏览器上输出仍显示- 4到5,但是控制台显示了以下内容:
counter=1
counter=2
counter=3
counter=4
counter=5
counter=6
counter=7
counter=8
counter=9
counter=10
如果使用的是Tomcat,还会发现这些记录已经追加到logs目录中stdout.log文件的最后。
对代码做以下修改,以便更清楚地看出到底发生了什么:
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>JSP Page</title></head>
<body>
<c:forEach var="loopCount" begin="1" end="10" step="1" >
<c:set var="myCount" value="${loopCount-5}" />
<c:out value="${myCount}"/></br>
<%
System.out.println(
"loopCount="
+ pageContext.findAttribute("loopCount")
+ " myCount="
+ pageContext.findAttribute("myCount")
);
%>
</c:forEach>
</body>
</html>
实验解析
这回把它命名为Example4.jsp。这里做了好几处修改,有些是为了便于调试,并增加代码的可读性。先要增加下面这行代码:
<c:set var="myCount" value="${loopCount-5}" />
它把loopCount-5的值存储到一个变量中,以便记录这个值。把中间计算结果保存在变量中,这个想法往往很不错,这样就能在需要时检查分析。为了更容易区分变量名,把循环变量count改为loopCount,然后将取值为–5到5的变量命名为myCount。最后,再对println 语句做点改进,让它同时打印循环计数器和我们关心的myCount 值。再次运行程序时,控制台输出如下:
loopCount=1 myCount=-4
loopCount=2 myCount=-3
loopCount=3 myCount=-2
loopCount=4 myCount=-1
loopCount=5 myCount=0
loopCount=6 myCount=1
loopCount=7 myCount=2
loopCount=8 myCount=3
loopCount=9 myCount=4
loopCount=10 myCount=5
现在就能很清楚地看到,如果要打印–5到5,loopCount就应该从0开始,而不是从1开始。
你可能会奇怪,为什么不在scriptlet里做减法。pageContext.findAttribute() 返回的值类型为Object。在进行算术运算之前,这些对象必须转换成数字类型。 使用内置的表达式语言和JSTL来完成这些操作要比在Java scriptlet中完成更为容易。
c:out和c:set标记是核心JSTL标记的标准部分,JSTL标记在《JSP程序设计》第6章有详细的介绍。使用这些标记,并且将EL表达式(参见《JSP程序设计》第5章)限制为只能是标记的属性,就能保证这个例子 与JSP 1.1和JSP 2规范都兼容。
Println 作为一种测量代码的方法,可以更好地观察代码执行时发生了什么。希望大家能从中了解到使用println语句对于调试代码的意义。不过,println 只是一个非常原始的特性,还有更好的办法来测量JSP并记录可能发生的动作。







