• 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%logslocalhost.当前日期.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属性

  • 相关阅读:
    记一次文件转码与二进制查看学习
    JAVA线程池 之 Executors (二) 原理分析
    JAVA线程池 之 Executors (一) 简介
    问题:部分mysql版本问题
    Java中一个方法字节码的长度会影响程序并发下的性能?
    AccessController.doPrivileged
    Nginx配置WebService、MySQL、SQL Server、ORACLE等代理
    C# 序列化Json时如何忽略JsonProperty(PropertyName =“ someName”)
    C# 文件上传(另一台服务器的共享目录)
    C# 导入Excel读取图片上传
  • 原文地址:https://www.cnblogs.com/shuenjian901/p/3404680.html
Copyright © 2020-2023  润新知