04. Servlet 异常处理&日志调试

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);
      
      //接下去的代码流程
      ....... 
    } 
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值