欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析Java Web錯(cuò)誤/異常處理頁面

 更新時(shí)間:2016年03月07日 10:56:04   作者:zhangxin09  
這篇文章主要和大家一起對(duì)Java Web錯(cuò)誤/異常處理頁面進(jìn)行分析研究,感興趣的小伙伴們可以參考一下

發(fā)生服務(wù)器 500 異常,如果默認(rèn)方式處理,則是將異常捕獲之后跳到 Tomcat 缺省的異常頁面,如下圖所示。

不論哪個(gè)網(wǎng)站都是一樣的,所以為了滿足自定義的需要,Tomcat 也允許自定義樣式的。也就是在 web.xml 文件中配置:

<error-page> 
  <error-code>500</error-code> 
  <location>/error.jsp</location> 
</error-page> 

首先說說自帶的邏輯。如果某個(gè) JSP 頁面在執(zhí)行的過程中出現(xiàn)了錯(cuò)誤, 那么 JSP 引擎會(huì)自動(dòng)產(chǎn)生一個(gè)異常對(duì)象,如果這個(gè) JSP 頁面指定了另一個(gè) JSP 頁面為錯(cuò)誤處理程序,那么 JSP 引擎會(huì)將這個(gè)異常對(duì)象放入到 request 對(duì)象中,傳到錯(cuò)誤處理程序中。如果大家有寫 Servlet 的印象,這是和那個(gè)轉(zhuǎn)向模版 JSP 的 javax.servlet.forward.request_uri 一個(gè)思路,保留了原請(qǐng)求的路徑而不是 JSP 頁面的那個(gè)路徑。在錯(cuò)誤處理程序里,因?yàn)?page 編譯指令的 isErrorPage 屬性的值被設(shè)為 true,那么 JSP 引擎會(huì)自動(dòng)聲明一個(gè) exception 對(duì)象,這個(gè) exception 對(duì)象從 request 對(duì)象所包含的 HTTP 參數(shù)中獲得。

request 對(duì)象中包含的異常信息非常豐富,如下所示:

你可以用 Java 語句 request.getAttribute("javax.servlet.error.status_code") 獲取,也可以在 JSP 頁面中通過 EL 表達(dá)式來獲取,如 ${requestScope["javax.servlet.error.status_code"]}。
這個(gè)自定義錯(cuò)誤頁面雖然簡單,JSP 本身也有很好的封裝結(jié)果,我也看過別人不少的資源,但細(xì)究之下也有不少“學(xué)問”,于是我想重新再”磨磨這個(gè)輪子“——首先 location 是一個(gè) jsp 頁面,也可以是 servlet,不過萬一 servlet 也有可能啟動(dòng)不起來的話那就使用簡單的 JSP 頁面就好了。我們通過 JSP 頁面定義內(nèi)部類的方法,達(dá)到頁面與邏輯的分離(無須編寫 servlet)。其余的思路如下:

在 JSP 里面完成 ErrorHandler 類,另有頁面調(diào)用這個(gè) ErrorHandler 類
不但可以接受 JSP 頁面的錯(cuò)誤,也可接受 servlet 的控制器傳遞的錯(cuò)誤,并且提取盡量多信息
全部內(nèi)容先寫到內(nèi)存,然后分別從兩個(gè)輸出流再輸出到頁面和文件
把錯(cuò)誤信息輸出到網(wǎng)頁的同時(shí),簡單加幾句話,可以把網(wǎng)頁上的信息也寫一份到數(shù)據(jù)庫或者文本
可以返回 HTML/JSON/XML
實(shí)現(xiàn)代碼如下:     

/** 
 * 異常處理類 
*/ 
class ErrorHandler { 
  // 全部內(nèi)容先寫到內(nèi)存,然后分別從兩個(gè)輸出流再輸出到頁面和文件 
  private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
  private PrintStream printStream = new PrintStream(byteArrayOutputStream); 
 
  /** 
   * 收集錯(cuò)誤信息 
   * @param request 
   * @param exception 
   * @param out 
   */ 
  public ErrorHandler(HttpServletRequest request, Throwable exception, JspWriter out) { 
    setRequest(request); 
    setException(exception); 
 
    if(out != null) { 
      try { 
        out.print(byteArrayOutputStream); // 輸出到網(wǎng)頁 
      } catch (IOException e) { 
        e.printStackTrace(); 
      } 
    } 
     
     log(request); 
     
    if(byteArrayOutputStream != null) 
      try { 
        byteArrayOutputStream.close(); 
      } catch (IOException e) { 
        e.printStackTrace(); 
      } 
    if(printStream != null) printStream.close(); 
  } 
 
  /** 
   * 
   * @param request 
   */ 
  private void setRequest(HttpServletRequest request) { 
    printStream.println(); 
    printStream.println("用戶賬號(hào):" + request.getSession().getAttribute("userName")); 
    printStream.println("訪問的路徑: "  + getInfo(request, "javax.servlet.forward.request_uri", String.class)); 
    printStream.println("出錯(cuò)頁面地址: " + getInfo(request, "javax.servlet.error.request_uri", String.class)); 
    printStream.println("錯(cuò)誤代碼: "   + getInfo(request, "javax.servlet.error.status_code", int.class)); 
    printStream.println("異常的類型: "  + getInfo(request, "javax.servlet.error.exception_type", Class.class)); 
    printStream.println("異常的信息: "  + getInfo(request, "javax.servlet.error.message", String.class)); 
    printStream.println("異常servlet: " + getInfo(request, "javax.servlet.error.servlet_name", String.class)); 
    printStream.println(); 
     
    // 另外兩個(gè)對(duì)象 
    getInfo(request, "javax.servlet.jspException", Throwable.class); 
    getInfo(request, "javax.servlet.forward.jspException", Throwable.class); 
 
    Map<String, String[]> map = request.getParameterMap(); 
 
    for (String key : map.keySet()) { 
      printStream.println("請(qǐng)求中的 Parameter 包括:"); 
      printStream.println(key + "=" + request.getParameter(key)); 
      printStream.println(); 
    } 
     
    for (Cookie cookie : request.getCookies()){ // cookie.getValue() 
      printStream.println("請(qǐng)求中的 Cookie 包括:"); 
      printStream.println(cookie.getName() + "=" + cookie.getValue()); 
      printStream.println(); 
    } 
 
  } 
 
  /** 
   * 
   * @param exception 
   */ 
  private void setException(Throwable exception) { 
    if (exception != null) { 
      printStream.println("異常信息"); 
      printStream.println(exception.getClass() + " : " + exception.getMessage()); 
      printStream.println(); 
 
      printStream.println("堆棧信息"); 
      exception.printStackTrace(printStream); 
      printStream.println(); 
    } 
  } 
 
    /** 
     * 
     * @param request 
     */ 
    private void log(HttpServletRequest request) { 
      File dir = new File(request.getSession().getServletContext().getRealPath("/errorLog")); 
      if (!dir.exists()) { 
        dir.mkdir(); 
      } 
       
      String timeStamp = new java.text.SimpleDateFormat("yyyyMMddhhmmssS").format(new Date()); 
      File file = new File(dir.getAbsolutePath() + File.separatorChar + "error-" + timeStamp + ".txt"); 
       
//       try(FileOutputStream fileOutputStream = new FileOutputStream(file); 
//         PrintStream ps = new PrintStream(fileOutputStream)){// 寫到文件 
//         ps.print(byteArrayOutputStream); 
//       } catch (FileNotFoundException e) { 
//         e.printStackTrace(); 
//       } catch (IOException e) { 
//         e.printStackTrace(); 
//       } catch (Exception e){ 
//         e.printStackTrace(); 
//       } 
    } 
 
    /** 
     * 
     * @param request 
     * @param key 
     * @param type 
     * @return 
     */ 
    @SuppressWarnings("unchecked") 
    private <T> T getInfo(HttpServletRequest request, String key, Class<T> type){ 
      Object obj = request.getAttribute(key); 
      return obj == null ? null : (T) obj; 
    }  
} 

這樣就可以完成異常的控制了。下面定義 web.xml,讓 tomcat 出錯(cuò)引向我們剛才指定的頁面 error.jsp

<!-- 404 頁面不存在錯(cuò)誤 --> 
<error-page> 
  <error-code>404</error-code> 
  <location>/WEB-INF/jsp/common/default/error.jsp</location> 
</error-page> 
<!-- // --> 
 
<!-- 500 服務(wù)器內(nèi)部錯(cuò)誤 --> 
<error-page> 
  <error-code>500</error-code> 
  <location>/WEB-INF/jsp/common/default/error.jsp</location> 
</error-page> 
<!-- // --> 

我們安排一個(gè)默認(rèn)的頁面如下

源碼如下:

<%@page pageEncoding="UTF-8" isErrorPage="true"%> 
<%@ include file="/WEB-INF/jsp/common/ClassicJSP/util.jsp"%> 
<!DOCTYPE html> 
<html> 
<head> 
  <title>錯(cuò)誤頁面</title> 
  <style> 
    body { 
      max-width: 600px; 
      min-width: 320px; 
      margin: 0 auto; 
      padding-top: 2%; 
    } 
     
    textarea { 
      width: 100%; 
      min-height: 300px; 
    } 
     
    h1 { 
      text-align: right; 
      color: lightgray; 
    } 
     
    div { 
      margin-top: 1%; 
    } 
  </style> 
</head> 
<body> 
  <h1>抱 歉!</h1> 
  <div style="padding:2% 0;text-indent:2em;">尊敬的用戶:我們致力于提供更好的服務(wù),但人算不如天算,有些錯(cuò)誤發(fā)生了,希望是在控制的范圍內(nèi)……如果問題重復(fù)出現(xiàn),請(qǐng)向系統(tǒng)管理員反饋。</div> 
  <textarea><% 
      new ErrorHandler(request, exception, out); 
      %></textarea> 
  <div> 
    <center> 
      <a href="${pageContext.request.contextPath}">回首頁</a> | <a href="javascript:history.go(-1);">上一頁</a> 
    </center> 
  </div> 
</body> 
</html> 

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

最新評(píng)論