chap 9 错误处理和debugging

来源:互联网 发布:mac滴管粉底液好用吗 编辑:程序博客网 时间:2024/06/11 18:52
chap 9 错误处理和debugging
9.1 处理语法错误
(1) jsp container要求每个jsp element 都按照spec.的规定书写。
9.1.1 element语法错误
[例子] <%@ page contentType="text/html" >
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> (tomcat在浏览器中显示的错误)
org.apache.jasper.JasperException: /ch9/error1.jsp(1,1) Unterminated &lt;%@ page tag
(1) jsp spec.只要求container返回server errorhttp status code500)。如何报告细节,取决于具体container
(2) exception stack tracetomcat在页面中显示的详细错误信息。 [原理]java方法内出现错误时,通常抛出一个exception,表示它不知道如何处理该问题。有时候程序的另一部分能处理该问题,但更多情况下,最好向用户报告错误。
(3) /ch9/error1.jsp表示出错的页面。(1,1)表示第1行,第1个字符。Unertminated &lt;%@ page tag表示<%@没有正常结尾。
[例子]
1 + 2 + 3 = <c:out value="${1 + 2 + 3}" >
tomcat提示的错误)
/ch9/error2.jsp(14,0) Unterminated &lt;c:out tag
[例子]
1 + 2 + 3 = <c:out valu="${1 + 2 + 3}" />
tomcat提示的错误)
/ch9/error3.jsp(11,16) According to the TLD or the tag file, attribute value is mandatory for tag out

[注意]如果属性是必需的,tomcat报告丢失;如果属性是可选的,tomcat报告是错误属性名。
[例子]
1 + 2 + 3 = <c:out value="${1 + 2 + 3} default="Doh!" />
tomcat提示的错误)
/ch9/error4.jsp(11,55) equal symbol expected []因为container"${1 + 2 + 3} default="整个当作了value的值,而Doh!被当成了属性。
(4) 假如action没被执行,最好检查一下是否漏掉/写错了taglib directive
9.1.2 jstl EL语法错误
[例子]
1 + 2 + 3 = <c:out value="$1 + 2 + 3" />
[]tomcat不报错。结果显示为 1 + 2 + 3 = $1 + 2 + 3[]value对应的java类型是Object
[例子]
1 + 2 + 3 = <c:out value="${1 + 2 + 3" />
tomcat提示的错误)
<h3>Validation error messages from TagLibraryValidator for c</h3><p>1: tag = 'out' / attribute = 'value': An error occurred while parsing custom action attribute "value" with value "${1 + 2 + 3": Encountered "<EOF>", expected one of ["}", ".", ">", "gt", "<", "lt", "==", "eq", "<=", "le", ">=", "ge", "!=", "ne", "[", "+", "-", "*", "/", "div", "%", "mod", "and", "&&", "or", "||"]</p> []这个错误信息是由jstl RItranslation-phase validator产生的。
[例子]
The Current URI: <c:out value="${pageContext.request.requestUri}" />
tomcat提示的错误)
 An error occurred while evaluating custom action attribute "value" with value "${pageContext.request.requestUri}": Unable to find a value for "requestUri" in object of class "org.apache.coyote.tomcat5.CoyoteRequestFacade" using operator "." (null)
(1)错误原因:requestUri,应当是requestURI (2)这个错误信息在request time才被报告。
[例子]
The missing parameter: <c:out value="${param.misspelled}" />
tomcat不报告错误) (1) ${param.misspelled}被算作null,再由<c:out>转换成空字符串 (2)这是有意设计的:[1]好的方面:可以避免判断parameter是否missing[不好的方面]难以找到parameter的拼写错误

9.2 Debugging jsp app
(1) debugging:发现并修改Logic error
(2) debugger:对于compiled languagejavacc++)等,用于逐行前进程序,或直至抵达break point才停止,这时可以检查程序中所有变量的值。 []IBMVisual Age for Java(即eclipse的前驱)提供了适用于jspdebugger
(3)但是一个真正的debugger对于jsp可谓overkill。对于复杂的页面,可以把代码从页面转移到JavaBeancustom action中。然后可以用标准的java debugger对这些组件除错。
(4) debug的另一种方法:添加代码,从而打印出变量的value [例子]添加代码
${param.submitted}: <c:out value="${param.submitted}" /><br>
${param.userName}:  <c:out value="${param.userName}" /><br>
${param.submitted || empty param.userName}:
  <c:out value="${param.submitted || empty param.userName}" />

(5) 有时候需要将debug 信息打印到log文件中,或启动server时的command window中。
(6) 打印到log文件中:
<ora:fileWrite fileName="log"> []log文件的名称、路径取决于container。对于tomcat,可设置成对每个app有一个单独的文件。但默认写到logs/<hostname>_log.<date>.txt中。本例中,log<ora:fileWrite>keywordfileName中也可以是一个绝对路径。 []如果没有指定fileName,就打印到command window中。
(7) 如果不希望在production code中有debug信息,就不能用<ora:fileWrite>,可以用<ora:debug> []仅当request中包含一个debug request parameter时,例如http://localhost:8080/ora/ch9/debug.jsp?debug=resp+stdout&a=b,才会激活页面中的debug action

9.3 处理runtime error
(1)有些问题不能被component很好地处理,就需要告诉userJava一般使用抛出exception
(2) beanjsp actionEL processor都能抛出exception。缺省时,jsp捕获exception,再将消息及stack trace显示在browser中。
(3) 但这样的消息一方面,不方便app user查看;另一方面,从安全上不可靠(可能包含文件路径、sql语句等信息)。
(4) 可以告诉jsp container使用自定义的错误页面。
[例子]
<%@ page errorPage="errorpage.jsp?debug=log" %>
<c:set var="sourcePage" scope="request"
  value="${pageContext.request.requestURI}" />
(1) page directiveerrorPage属性表示:如果有任何jsp元素抛出异常时,将显示的页面的路径。 (2) 上例中,errorpage.jsp必须跟引用它的页面在一个目录下。 (3) 如果以/开头,就表示一个context-relative路径,相对于appcontext path
[例子]
errorpage.jsp中,
<%@ page isErrorPage="true" %>
……
<ora:fileWrite fileName="log">
      Error in: <c:out value="${sourcePage}" />
      Error message: <c:out value="${pageContext.exception.message}" />
</ora:fileWrite>
(1) isErrorPage被设为true,告诉container隐性的pageContext变量的exception属性应当被初始化,指向造成该页面被invokeexception。该属性的类型是java.lang.Throwable (2) java.lang.Throwable包含一个message属性,表示什么地方出了错。 (3) sourcePage变量是在上一个例子中创建的。

(5) 除了上面的方法,指定error page的另一种方法是:在app deployment descriptor中声明error page
[例如]
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/errorpage.jsp</location>
</error-page>
[]如果在页面中同时指定了errorPage属性,就以该属性为准。
9.3.1 catching exception [例子]
<c:catch var="error">
<c:set var="currentNumber" value="${calc.currentNumber}" />
</c:catch>
<c:if test="${error != null}">
<c:set var="currentNumber" value="Error" />
<jsp:setProperty name="calc" property="reset" value="true" />
</c:if>
(1) <c:catch>var属性表示用于放置java.lang.Throwable的变量名,对应的异常是body中的element可能抛出的。 (2) 本例中,calc.currentNumber是计算函数。