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 <%@ page tag |
(1) jsp spec.只要求container返回server error的http status code(500)。如何报告细节,取决于具体container |
(2) exception stack trace:tomcat在页面中显示的详细错误信息。 |
[原理]当java方法内出现错误时,通常抛出一个exception,表示它不知道如何处理该问题。有时候程序的另一部分能处理该问题,但更多情况下,最好向用户报告错误。 |
(3) /ch9/error1.jsp表示出错的页面。(1,1)表示第1行,第1个字符。Unertminated <%@ page tag表示<%@没有正常结尾。 |
[例子] 1 + 2 + 3 = <c:out value="${1 + 2 + 3}" > (tomcat提示的错误) /ch9/error2.jsp(14,0) Unterminated <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 RI的translation-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 language(java、c、c++)等,用于逐行前进程序,或直至抵达break point才停止,这时可以检查程序中所有变量的值。 |
[注]IBM的Visual Age for Java(即eclipse的前驱)提供了适用于jsp的debugger。 |
(3)但是一个真正的debugger对于jsp可谓overkill。对于复杂的页面,可以把代码从页面转移到JavaBean或custom 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>的keyword;fileName中也可以是一个绝对路径。 |
[注]如果没有指定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很好地处理,就需要告诉user。Java一般使用抛出exception。 |
(2) bean、jsp action、EL 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 directive的errorPage属性表示:如果有任何jsp元素抛出异常时,将显示的页面的路径。 |
(2) 上例中,errorpage.jsp必须跟引用它的页面在一个目录下。 |
(3) 如果以/开头,就表示一个context-relative路径,相对于app的context 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属性应当被初始化,指向造成该页面被invoke的exception。该属性的类型是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是计算函数。 |
chap 9 错误处理和debugging
最新推荐文章于 2020-12-24 05:04:14 发布