6.3.3 JSP页面中的异常处理
JSP页面可以通过page指令的errorPage和isErrorPage属性进行异常处理。errorPage属性要用在抛出异常的JSP页面,该属性指定了处理异常的页面(一般是JSP页面)。generator_error.jsp页面是一个抛出异常的JSP页面,代码如下:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" errorPage="deal_error.jsp"%>
<%
out.println("发生错误之前");
//抛出java.lang.ClassNotFoundException异常
Class.forName("NoExist");
out.println("发生错误之后");
%>
在上面的代码中使用forName方法动态装载了一个不存在的NoExist类,因此会抛出ClassNotFoundException异常,如果不使用errorPage属性,异常信息将直接在访问generate_error.jsp页面时在浏览器中显示。但如果使用了errorPage属性,就可以在另外一个处理异常的JSP页面由开发人员决定如何处理抛出的异常。
处理异常的页面为deal_error.jsp,代码如下:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"
isErrorPage="true"%>
<%
out.println("<font color='#FF0000'>异常信息</font><hr>");
exception.printStackTrace(new java.io.PrintWriter(out));
%>
在deal_error.jsp页面中使用了page指令的isErrorPage属性。如果将该属性设为true,则JSP引擎在翻译deal_error.jsp页面时会建立exception对象,因此,在deal_error.jsp页面中可以直接使用exception对象。
在浏览器地址栏中输入如下的URL:
http://localhost:8080/demo/chapter6/generate_error.jsp
浏览器显示的信息如图6.4所示。
图6.4 显示抛出的异常信息
除了通过errorPage属性指定处理异常的JSP页面外,还可以在web.xml文件中配置处理异常的JSP页面。由于_jspService方法只能抛出java.io.IOException和javax.servlet.ServletException异常,而且在抛出java.lang.RuntimeException异常时不需要在方法定义中显式地声明,因此,在web.xml文件中只能配置处理如下三种异常类及其子类的JSP页面:
l java.io.IOException
2 javax.servlet.ServletException
3 java.lang.RuntimeException
除了上述三种异常,其他的异常将在_jspService内部进行处理。
下面将在generate_error.jsp页面中编写如下的代码:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
if("servlet".equals(request.getParameter("error")))
{
throw new ServletException("Servlet异常");
}
else if("io".equals(request.getParameter("error")))
{
throw new java.io.IOException("IO异常");
}
else
{
int i = 1 / 0;
}
%>
从上面的代码可以看出,在page指令中并未指定errorPage属性,这是因为如果指定errorPage属性,系统将会优先考虑errorPage属性的设置,也就是说,系统会使用errorPage属性所指的异常处理页面,而不会考虑在web.xml文件中配置的异常处理页面。因此,要想使用web.xml文件来配置异常处理页面,就不能在抛出异常的页面中的paga指令中指定errorPage属性。
新建一个处理异常的deal_error1.jsp页面,代码如下:
<%@page import="java.io.PrintStream"%><%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>
<%
out.println("<font color='#FF0000'>异常信息(deal_error1.jsp)</font><hr>");
out.println(exception.getMessage());
exception.printStackTrace(new java.io.PrintWriter(out));
%>
为了处理上述三种异常,需要在web.xml文件中添加如下的配置代码:
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/chapter6/deal_error1.jsp</location>
</error-page>
<error-page>
<exception-type>java.io.IOException</exception-type>
<location>/chapter6/deal_error1.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/chapter6/deal_error1.jsp</location>
</error-page>
从上面的配置代码可以看出,使用了三个<error_page>元素分别用来配置上述三类异常的处理页面。在<error_page>元素中有两个子元素:<exception-type>和<location>,其中<exception-type>元素用来指定异常类名,<location>元素用来指定异常处理页的路径,必须以“/”开头,表示相对当前Web应用程序的根目录。
读者可以在浏览器地址栏中输入如下三个URL来测试上述三种异常的处理情况:
http://localhost:8080/demo/chapter6/generate_error.jsp?error=servlet
http://localhost:8080/demo/chapter6/generate_error.jsp?error=io
http://localhost:8080/demo/chapter6/generate_error.jsp
处理Servlet异常时的输出结果如图6.5所示。
图6.5 处理Servlet异常
<error-page>元素除了可以使用<exception-type>元素指定异常类外,还可以使用<error-code>元素指定HTTP响应状态码,如下面的配置代码所示:
<error-page>
<error-code>404</error-code>
<location>/images/error.jpg</location>
</error-page>
上面的配置代码使用<error-code>元素设置了HTTP响应状态码404,这就意味着访问所有在服务端不存在的Web资源,从页产生404状态码的请求,都会交由<location>元素所指定的异常处理页面来处理。在该例中指定了一个图像文件(error.jpg),读者也可以在<location>元素中指定其他的Web资源,如HTML页面、JSP页面等。
在使用web.xml文件配置异常处理页面时要注意,<error_code>和<exception-type>元素只能同时在一个<error-page>元素中出现一个。