Servlet 异常处理
- 对于 Servlet 的异常处理,整个流程同 Java SE 中的 异常处理一样,一样使用 throw 抛出异常,在代码中捕获异常后进行处理,但是在 Servlet 中可以使用 <error-page> 元素来对特定的异常或 HTTP 状态码调用相应的 Servlet 进行处理;
- Servlet 中的异常捕获机制是这样的:当一个 Servlet 抛出异常时,Web 容器在使用了 exception-type 的 web.xml 中搜索与抛出异常类型相匹配的配置;
在 web.xml 中进行配置
假如有一个命名为 error.ErrorHandler 的 Servlet 在 Web 应用抛出 404,403 状态码和 ServletException,IOException 时会被调用,其在 web.xml 中的配置如下:
<!--对ErrorHandler进行Servlet的配置和映射配置-->
<servlet>
<servlet-name>ErrorHandler</servlet-name>
<servlet-class>error.ErrorHandler</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorHandler</servlet-name>
<url-pattern>/ErrorHandler</url-pattern>
</servlet-mapping>
<!--进行错误状态码403,404的相关 error-page 配置-->
<error-page>
<error-code>404</error-code>
<location>/ErrorHandler</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/ErrorHandler</location>
</error-page>
<!--进行ServletException,IOException异常相关的 error-page 配置-->
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/ErrorHandler</location>
</error-page>
<error-page>
<exception-type>java.io.IOException</exception-type>
<location>/ErrorHandler</location>
</error-page>
当然如果要对所有的异常类型配置一个通用的错误处理 Servlet,那么只要对 java.lang。Throwable配置error-page即可,如下:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/ErrorHandler</location>
</error-page>
Servlet 异常请求属性
Servlet 中提供了一系列的可访问请求属性列表,用于分析错误异常的性质,在 Sevlet抛出异常时,相应的异常类型或状态码信息会被添加到这些请求属性列表中;
javax.servlet.error.status_code
|
该属性给出状态码,状态码可被存储,并在存储为 java.lang.Integer 数据类型后可被分析。
|
javax.servlet.error.exception_type
|
该属性给出异常类型的信息,异常类型可被存储,并在存储为 java.lang.Class 数据类型后可被分析。
|
javax.servlet.error.message
|
该属性给出确切错误消息的信息,信息可被存储,并在存储为 java.lang.String 数据类型后可被分析。
|
javax.servlet.error.request_uri
|
该属性给出有关 URL 调用 Servlet 的信息,信息可被存储,并在存储为 java.lang.String 数据类型后可被分析。
|
javax.servlet.error.exception
|
该属性给出异常产生的信息,信息可被存储,并在存储为 java.lang.Throwable 数据类型后可被分析。
|
javax.servlet.error.servlet_name
|
该属性给出 Servlet 的名称,名称可被存储,并在存储为 java.lang.String 数据类型后可被分析。
|
这些属性可以通过 request.getAttribute(String errorName) 获取,具体使用见下面实例;
Servlet 异常处理程序示例
以下简要地实现 error.ErrorHandler 类,相关的 web.xml 见上面;
package error
public class ErrorHandler extends GenericServlet {
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{
//获取异常信息
Throwable throwable = (Throwable)request.getAttribute("javax.servlet.error.exception");
Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
String servletName = (String)request.getAttribute("javax.servlet.error.servlet_name");
if (servletName == null)
servletName = "Unknown";
String requestUri = (String)request.getAttribute("javax.servlet.error.request_uri");
if (requestUri == null)
requestUri = "Unknown";
// 设置响应内容类型,也可以直接转发到JSP页面进行显示,或者直接发送到日志
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>\n" +
"<html>\n" +
"<head><title>Error</title></head>\n" +
"<body>\n"+
"<h1>Error</h1>\n");
if (throwable == null && statusCode == null){
out.println("<h2>Error message missing </h2>");
}else if (statusCode != null) {
out.println("Error code : " + statusCode);
}else{
out.println("<h2>Error Message</h2>");
out.println("Servlet Name : " + servletName + "</br></br>");
out.println("Error Type : " + throwable.getClass( ).getName( ) + "</br></br>");
out.println("Request URI: " + requestUri + "<br><br>");
out.println("Error message: " + throwable.getMessage( ));
}
out.println("</body></html>");
}
}
Servlet 消息日志
- 在进行 Servlet 的调试时,比较常用的有2种方法;
- 一种同 Java SE 一样直接使用 System.out.println() 进行简单快捷地调试;
- 另外一种是使用适当的日志记录方法,可以使用 log4j 来进行系统的日志记录,Servlet API 中提供了一种简单的日志输出方式,使用 GenericServlet 或 HttpServlet 的 log() 方法,或者 ServletContext 的 log() 方法;
- 通过 Servlet API 生成的日志记录在 【Tomcat根目录/logs目录】中可以找到;
关于 GenericServlet、HttpServlet 、ServletContext 的 log() 方法的 API
log(String msg) | 向 Servlet 的日志文件中写入日志 |
log(String message,java.lang.Throwable throwable) | 向 Servlet 的日志文件中写入错误日志,和异常堆栈信息 |
以下是简单的代码示例;
public class Demo extends GenericServlet {
public void service(ServletRequest request, ServletResponse response) throws ServletException,java.io.IOException {
String par = request.getParameter("parameter1");
ServletContext context = getServletContext( );
if (par == null || par.equals(""))
context.log("No message received:",new IllegalStateException("Missing parameter"));
else
context.log("Here is the visitor's message: " + par);
//接下去的代码流程
.
}
}