Servlet的异常处理机制

一 声明式异常处理
 
在web.xml中对声明对各种异常的处理方法。
通过 <error-page>元素来声明。 此元素的结构如下:
 
                 +------<error-code> or <exception-type>
                 |
<error-page> ----+
                 |
                 +------<location>
 
 
1 HTTP错误代码的处理
     4**代码表示客户端错误:请求有语法错误或者请求无法实现。
     5**代码表示服务器端错误:服务器未能实现合法的请求。
 
例:为404错误指定相应的错误处理页面
    在web.xml中
 
  1. <error-page>
  2.         <error-code>404</error-code>
  3.         <location>/FileNotFound.html</location>
  4. </error-page>
    编写FileNotFound.html
  
同时 也可以编写一个专门处理HTTP错误代码的HttpErrorHandlerServlet类来进行响应
  1. package servlet;
  2. import java.io.PrintWriter;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. public class HttpErrorHandlerServlet extends HttpServlet
  8. {
  9.     protected void service(HttpServletRequest req, HttpServletResponse resp)
  10.                     throws ServletException, java.io.IOException
  11.     {
  12.         resp.setContentType("text/html;charset=GB2312");
  13.         PrintWriter out = resp.getWriter();
  14.         
  15.         Integer status_code=(Integer)req.getAttribute("javax.servlet.error.status_code");
  16.         
  17.         out.println("<html><head><title>错误页面</title></head>");
  18.         out.println("<body>");
  19.         
  20.         //如果你的JDK版本低于1.5,那么你应该按照如下方式调用
  21.         //int status=status_code.intValue();
  22.         //switch(status){...}
  23.         switch(status_code)
  24.         {
  25.         case 401:
  26.             break;
  27.         case 404:
  28.             out.println("<h2>HTTP状态代码:"+status_code+"</h2>");
  29.             out.println("你所访问页面并不存在,或者已经被移动到其它位置。");
  30.             out.println("

    如有其它问题,请<a href=mailto:admin@sunxin.org>联系管理员</a>。");

  31.             break;
  32.         default:
  33.             break;
  34.         }
  35.         out.println("</body></html>");
  36.         out.close();
  37.     }
  38. }
 
重写HttpServlet类的service()方法。调用请求对象getAttribute()方法得到javax.servlet.error.status_code属性的值,当发生HTTP错误的时候,
Servlet容器会自动将HTTP的错误代码作为javax.servlet.error.status_code
属性的值,保存在请求的对象中。
部署好这个servlet。location修改为servlet的location
 
2  Java异常的处理
 
例:一个Servlet从文件中读取配置信息,如果文件不存在的,就会抛出java.io.FileNotFoundException异常。
 
====第一步:FileExceptionServlet.java
  1. package org.sunxin.ch06.servlet;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.util.Properties;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. public class FileExceptionServlet extends HttpServlet
  10. {
  11.     public void doGet(HttpServletRequest req, HttpServletResponse resp)
  12.                throws ServletException,IOException
  13.     { 
  14.         FileInputStream fis=new FileInputStream("config.inc");
  15.         Properties pps=new Properties();
  16.         pps.load(fis);
  17.         
  18.         //读取属性的代码,省略。
  19.         
  20.         fis.close();
  21.     }
  22. }
如果找不到config.inc文件,FileExceptionServlet就会抛出java.io.FileNotFoundException异常
 
========第二步:异常处理Servlet类。ExceptionHandlerServlet.java
 
  1. package servlet;
  2. import java.io.PrintWriter;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. public class ExceptionHandlerServlet2 extends HttpServlet
  8. {
  9.     protected void service(HttpServletRequest req, HttpServletResponse resp)
  10.                     throws ServletException, java.io.IOException
  11.     { 
  12.         resp.setContentType("text/html;charset=GB2312");
  13.         PrintWriter out = resp.getWriter();
  14.         
  15.         out.println("<html><head><title>错误页面</title></head>");
  16.         out.println("<body>");
  17.         
  18.         String uri=(String)req.getAttribute("javax.servlet.error.request_uri");
  19.         Object excep=req.getAttribute("javax.servlet.error.exception");
  20.         out.println(uri+" 运行错误。");
  21.         out.println("<p>错误原因:"+excep);
  22.         
  23.         out.println("</body></html>");
  24.         out.close();
  25.     }
  26. }
========第三步:web.xml文件中声明Servlet
  1. <error-page>
  2.         <exception-type>java.io.FileNotFoundException</exception-type>
  3.         <location>/ExcepHandler</location>
  4.     </error-page>
 
<exception-type>子元素指定了Java异常类的名字
<locaiton>子元素指定了对异常处理的Servlet类
 
 
二 程序式异常处理
程序式异常处理就是在Web程序中利用try-catch语句进行捕获异常,并对捕获异常进行响应的处理。
 
1  在try-catch语句中处理异常
  1. catch(SQLException se)
  2.         {
  3.             
  4.             getServletContext().log("ServletContext.log(): 数据库操作失败!"+
  5.                                     se.toString());
  6.             log("GenericServlet.log(): 数据库操作失败!"+se.toString());
  7.             resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  8.                         "数据库操作出现问题,请联系管理员。");
  9.         }
 
[1]  捕捉到异常时,分别用ServletContext接口的log()方法和GenericServlet抽象类的log()方法记录数据库操作失败的原因。
区别:
如果调用GenericServlet类的log()方法 它会在日志消息的前面加上Servlet的名字
而调用ServletContext接口的log()方法 则只记录消息本身
这两个log()方法会把日志信息写入到日志文件中。 在tomcat6 产生的日志文件名以及文件存放的位置是
%CATALINA_HOME%\logs\localhost.当前日期.log。
[2]  调用响应对象的sendError()方法发送HTTP错误代码,Servlet容器会发送一个包含了这些信息的错误页面到浏览器
 
2  使用RequestDispatcher来处理异常
 
产生异常的Servlet
  1. try
  2.         {
  3.             int a=5;
  4.             int b=0;
  5.             int c=a/b;
  6.         }
  7.         catch(ArithmeticException ae)
  8.         {
  9.             req.setAttribute("javax.servlet.error.exception",ae);
  10.             req.setAttribute("javax.servlet.error.request_uri",req.getRequestURI()); 
  11.             RequestDispatcher rd=req.getRequestDispatcher("ExcepHandler2");
  12.             rd.forward(req,resp);
  13.         }

处理异常的Servlet

 

  1. package servlet;
  2. import java.io.PrintWriter;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. public class ExceptionHandlerServlet2 extends HttpServlet
  8. {
  9.     protected void service(HttpServletRequest req, HttpServletResponse resp)
  10.                     throws ServletException, java.io.IOException
  11.     { 
  12.         resp.setContentType("text/html;charset=GB2312");
  13.         PrintWriter out = resp.getWriter();
  14.         
  15.         out.println("<html><head><title>错误页面</title></head>");
  16.         out.println("<body>");
  17.         
  18.         String uri=(String)req.getAttribute("javax.servlet.error.request_uri");
  19.         Object excep=req.getAttribute("javax.servlet.error.exception");
  20.         out.println(uri+" 运行错误。");
  21.         out.println("<p>错误原因:"+excep);
  22.         
  23.         out.println("</body></html>");
  24.         out.close();
  25.     }
  26. }

说明:

[1]  将异常对象和抛出异常的servlet的位置作为HttpServletRequest对象的属性保存到请求对象中。

[2]  通过请求对象的getRequestDispatcher()方法得到RequestDispatcher对象 调用RequestDispatcher对象的forward()方法将请求转发给 ExcepHandler2

[3]  ExcepHandler2可以从请求对象中取出javax.servlet.error.exception和javax.servlet.error.request_uri属性

posted @ 2013-11-03 09:55  shuenjian901  阅读(1134)  评论(0编辑  收藏  举报