1. JSP的错误信息页面:
1) 当浏览器请求JSP时发生异常就会返回一个错误信息页面;
2) 该页面中会显示一些和JSP源码有关的错误或是JSP转译成Java代码后产生的编译错误或是一些Java运行时的错误等,即错误信息里可能会爆出出错的JSP代码也可能爆出转译后的Java代码,信息多而纷乱,不同错误之间容易相互混淆;
3) 如何直击错误的根本原因:错误报告主要有4部分,分别是type、message、description、exception,前三者的作用不大,发生错误时前三者中会有什么都不显示的,并且大部分情况下前三者显示的信息完全相同,最重要的是exception的第一句话,这句话是泛白显示的,这句话会显示错误发生的地方、错误的类型和原因;
!!这句反白的话之后就是具体的各种错误异常列表了,一大堆一大堆的!!!
4) 三种主要的错误:
i. 转译错误:JSP页面本身就有一些语法错误,导致JSP无法正常转译为.java文件,这类错误会在反白语句中显示错误具体处在JSP文件的第几行,并说明错误的类型以及原因,比如/xxx.jsp(1, 2) Page directive: invalid value for buffer,就是指xxx.jsp文件的第1行第2个词语法错误,错误类型是指示元素发生错误,错误的原因是page指示类型的buffer属性设置错误,原因可能为buffer没写单位,比如应该写成"16kb",但是写成了"16";
ii. 编译错误:JSP页面可以正常转译为.java文件,接着就是将.java编译为.class文件,这种错误是发生在编译阶段,一种常见错误就是JSP中使用了某些类,但是这些类并没有部署到服务器上,虽然JSP可以正常转译,但是编译时因为找不到JSP中引用的类而导致编译错误,这类错误通常会在反白语句中显示为:Unable to compile class for JSP,接下来就是错误的具体内容了(直接显示出错的JSP代码行);
iii. 运行时错误:即编译好的.class正在执行时发生错误,这类错误就是纯Java运行时异常了,像最常见的Null Pointer Exception异常之类的,这类错误在反白语句中显示为:An exception occurred processing JSP page /xxx.jsp at line XXX,接着也是显示具体出错的JSP代码行;
!!注意,虽然后两者都属于Java错误,但是错误代码行显示的都不是转译后的.java源代码,而是JSP代码,这就需要用户清楚地了解JSP到Servlet的转换机制才能做到心里有底;
2. 自定义异常发生时的错误处理页面:
1) 只要定义page指示元素的errorPage属性就可以指定当前页面发生异常时应该交给哪个页面进行处理,例如:<%@page errorPage="error.jsp"%>,即如果当前页面发生异常则错误信息的显示以及错误的处理都交给error.jsp页面;
2) 而处理错误的页面必须要将page指示元素的isErrorPage属性的值设为true,否则无法接受其它页面抛出的异常,例如<%@page isErrorPage="true"%>;
3) 错误出来页面中使用exception隐式对象来显示错误信息,如果isErrorPage为false则exception无法接受其它页面抛来的异常;
4) exception的用法:
i. exception本身实现了toString方法,因此可以直接和字符串相连转化为错误类型信息字符串,在JSP中可以直接使用表达式元素进行输出,比如<%=exception%>,输出的内容就是错误页面中的反白语句!!
ii. 接着可以使用exception的printStackTrace来打印异常发生时的堆栈跟踪信息(就是反白语句后面的一大坨错误信息):void Throwable.printStackTrace(PrintWriter s);
!!由于该方法需要传一个可供输出的PrintWriter对象,而在JSP中通常用隐式对象out进行输出,所以可以在Scriptlet中这样输出堆栈信息:
<% exception.printStackTrace(new PrintWriter(out)); %>
3. 在web.xml中统一部署页面错误的处理:
1) 如果有很多JSP页面的错误信息都将交给同一个页面进行处理,那么在每一个JSP页面中都要写一遍errorPage岂不是很麻烦;
2) 可以在web.xml中设定某种类型的异常或者某个状态码对应的异常都抛给同一个页面,那么这样的话就无需在JSP页面中标注errorPage页面也可以在发生异常时正确地抛给相应的错误处理页面;
3) 使用的标签是:<web-app>下的<error-page>标签,在<error-page>下有两种标签来分别表示不同形式的异常,一种是<exception-type>,即基于Java的异常类型,另一种是<error-code>,即基于HTTP错误代码的,接下来就是<location>标签,表示在上述异常发生时应该将异常转发给哪个URL指定的应用进行处理(Servlet或JSP都行);
!举例:
<web-app ...>
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/report.view</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
</web-app>
!!前者就是将所有java.lang.NullPointerException类型的异常都抛给report.view来处理,后者就是将所有HTTP 404 Error错误都抛给404.jsp页面进行处理;
4) web.xml的这种异常处理配置是全局的,针对所有环境目录下的应用程序,但是如果应用程序中同时也指定了errorPage,那么则以应用程序中指定的为准;
!!!如果web.xml和JSP页面中都没有设置错误页面,那么将使用Web容器默认的处理方式,即直接返回一个标准的错误页面;
5) 注意!对于使用error-code部署的错误处理的情况,使用HttpServletResponse的sendError方法也可以自动转到相应的错误处理页面:
void HttpServletResponse.sendError(int sc); // sc就是错误状态码,即以SC_打头的常数