首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

前面的例子就是我们所称的运行时bugruntime bug)。只有在执行程序的时候运行时bug才会暴露出来。Java程序会在执行之前先进行编译。编译器会提供一些消息来说明代码中存在的哪些错误导致了代码无法编译和执行。程序员在编译和执行程序之前必须先修正这些错误。不过,JSP通常在执行时才第一次编译。如果JSP编译无法通过,servlet容器通常会向浏览器返回一个消息说明问题。我们来看下一个实例。

实验1:编译时调试

首先修改上一个例子,在其中加入一个错误,导致它编译无法通过:

<%@page contentType="text/html"%>

<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/bore" %>

<html>

<head><title>JSP Page</title></head>

<body>

<c:forEach var="counter" begin="0" end="10" step="1" >

    <c:out value="${counter-5}"/><br/>

</c:forEach>

</body>

</html>

在上面这个例子中,我们把core改为bore,如果部署这个JSP并试图运行,就会得到图3-1所示的响应。

3-1 对编译未通过的JSP做出的响应

下面标出这里出现的问题,在此分行显示了这个消息,不过在原浏览器窗口中这个消息只有一行:

org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/

bore cannot be resolved in either web.xml or the jar files deployed with this

application

实验解析

Tomcat告诉我们,它无法找到http://java.sun.com/jsp/jstl/bore引用的东西。可以把这认为是我们科学方法中的观察。下面分析代码,找到Tomcat提示有问题的那一行,就是这个例子中突出显示的那一行。我们猜测 bore 应该是core。下面修改这行代码,把bore 替换为core。再次运行,可以注意到问题已经得到修正。

下面再来看一个例子,其中展示了在JSP中使用scriptlet时常犯的一个错误。

实验2JSP中使用Scriptlet时进行调试

下面的JSP要打印介于16之间的一个随机整数,将其命名为Example2.jsp

<%@page contentType="text/html"%>

<%@page pageEncoding="UTF-8"%>

<html>

<head><title>JSP Page</title></head>

<body>

  <% Random r = new Random();

     int i = r.nextInt(6)+1;

     out.println("value="+i);

  %>

</body>

</html>

执行这个JSP时,会返回以下错误:

org.apache.jasper.JasperException: Unable to compile class for JSP

 

An error occurred at line: 6 in the jsp file: /Sample2p1.jsp

 

Generated servlet error:

    [javac] Compiling 1 source file

 

C:\Documents and Settings\jtbell\.netbeans\3.6\jakarta-tomcat-

5.0.19_base\work\Catalina\localhost\begjsp\org\apache\jsp\Sample2p1_jsp.java:48:

cannot resolve symbol

symbol  : class Random

location: class org.apache.jsp.Sample2p1_jsp

 Random r = new Random();

 ^

An error occurred at line: 6 in the jsp file: /Sample2p1.jsp

 

Generated servlet error:

C:\Documents and Settings\jtbell\.netbeans\3.6\jakarta-tomcat-5.0.19_base\work\

Catalina\localhost\begjsp\org\apache\jsp\Sample2p1_jsp.java:48: cannot resolve

symbol

symbol : class Random

location: class org.apache.jsp.Sample2p1_jsp

 Random r = new Random();

               ^

 

An error occurred at line: 6 in the jsp file: /Sample2p1.jsp

 

Generated servlet error:

C:\Documents and Settings\jtbell\.netbeans\3.6\jakarta-tomcat-5.0.19_base\work\

Catalina\localhost\begjsp\org\apache\jsp\Sample2p1_jsp.java:49: incompatible types

found  : java.lang.String

required: int

     int i = r.nextInt(6)+1;

                       ^

3 errors

这里对响应做了编辑,并且调整了格式,以便在一个版面中能够放得下。

实验解析

同样的,这个程序未能通过编译,不过这一次是因为JSP生成的servlet代码中有一个Java错误。要记住,JSP会编译为一个Java servlet,这个servlet再编译为Java字节码。下面列出了前几行,从中可以看到出了问题:

org.apache.jasper.JasperException: Unable to compile class for JSP

 

An error occurred at line: 6 in the jsp file: /Sample2p1.jsp

 

Generated servlet error:

    [javac] Compiling 1 source file

JSP编译器(名为Jasper)无法编译这个JSP;错误发现在JSP的第6行,所生成的servlet也有这个错误。

接下来的几行提供了有关错误的具体信息。下面的文字告诉我们,问题出现在所生成的servlet的第48行,Java编译器无法解析一个符号:

C:\Documents and Settings\jtbell\.netbeans\3.6\jakarta-tomcat-

5.0.19_base\work\Catalina\localhost\begjsp\org\apache\jsp\Sample2p1_jsp.java:48:

cannot resolve symbol

再下面的几行指出,无法解析的是Random类:

symbol : class Random

location: class org.apache.jsp.Sample2p1_jsp

Random r = new Random();

^

最后一行的^符号指出了导致错误的代码位置。在这个例子中,它指向第一次使用Random的位置。

这一串错误提示会重复3遍,因为Java编译器报告它发现了3个错误。通常尽管报告了多个错误,但归根结底都是一个错误造成的,所以最好的办法是先解决第一个错误,然后再测试代码,看看其他的错误是不是也消除了。在这个例子中,第二段错误响应指示的是同一行上第二次使用Random的位置。第三个错误看上去也是相关的,所以稍后处理。

经观察,错误出现在JSP的第6行。下面需要对如何修正这个问题做出有根据的猜测。如果编译器找不到一个类,通常说明我们忘了加一条import 语句,或者import 语句或类拼写有误。通过快速审查代码,我们发现确实没有加任何 import 语句。下面加上正确的import 语句后再来执行这个代码,增加的代码行加阴影显示:

<%@page contentType="text/html" %>

<%@page pageEncoding="UTF-8" %>

<%@page import="java.util.Random" %>

<html>

<head><title>JSP Page</title></head>

<body>

  <% Random r = new Random();

     int i = r.nextInt(6)+1;

     out.println("value="+i);

  %>

</body>

</html>

这一次代码能成功编译,而且确实能按我们预想的那样正确地执行。我们根本不用去管第3个错误,因为它实际上只是前面两个错误的附带产物。

如果能预编译JSP就好了,这样就能在容器编译JSP之前先发现错误。预编译JSP还有一个好处:能得到更好的性能。第12章将介绍预编译如何改善性能。

 

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论