Javaweb異常提示資訊統一處理
Java異常封裝(自己定義錯誤碼和描述,附原始碼)
2016年01月29日 22:30:54 小寶鴿 閱讀數:23262 個人分類: Java基礎 所屬專欄: Java工作實用篇真正工作了才發現,Java裡面的異常在真正工作中使用還是十分普遍的。什麼時候該丟擲什麼異常,這個是必須知道的。
當然真正工作裡面主動丟擲的異常都是經過分裝過的,自己可以定義錯誤碼和異常描述。
下面小寶鴿就為大家介紹一個Java異常簡單封裝的例子。
在給出異常分裝例子之前,需要給大家普及Java裡面的checked異常和unchecked異常的個概念。
一、checked異常和unchecked異常
這裡之所以讓大家清楚checked異常和unchecked異常概念,是因為:待會我們的異常是繼承unchecked異常RuntimeException的。瞭解一下並無壞處嘛
checked異常:
表示無效,不是程式中可以預測的。比如無效的使用者輸入,檔案不存在,網路或者資料庫連結錯誤。這些都是外在的原因,都不是程式內部可以控制的。
必須在程式碼中顯式地處理。比如try-catch塊處理,或者給所在的方法加上throws說明,將異常拋到呼叫棧的上一層。
繼承自java.lang.Exception(java.lang.RuntimeException除外)。
unchecked異常:
表示錯誤,程式的邏輯錯誤。是RuntimeException的子類,比如IllegalArgumentException, NullPointerException和IllegalStateException。
不需要在程式碼中顯式地捕獲unchecked異常做處理。
繼承自java.lang.RuntimeException(而java.lang.RuntimeException繼承自java.lang.Exception)。
看下面的異常結構圖或許層次感更加深些:
二、異常分裝例項
2.1、新增一個列舉LuoErrorCode.java如下:
package com.luo.errorcode;
public enum LuoErrorCode {
NULL_OBJ("LUO001","物件為空"),
ERROR_ADD_USER("LUO002","新增使用者失敗"), UNKNOWN_ERROR("LUO999","系統繁忙,請稍後再試...."); private String value; private String desc; private LuoErrorCode(String value, String desc) { this.setValue(value); this.setDesc(desc); } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public String toString() { return "[" + this.value + "]" + this.desc; } }
注意!!!這裡我們重寫了LuoErrorCode的toString方法,至於為什麼要這樣,後面會提到,客觀請繼續看。
2.2、建立一個異常類BusinessException.java,繼承RuntimeException:
package com.luo.exception;
public class BusinessException extends RuntimeException { private static final long serialVersionUID = 1L; public BusinessException(Object Obj) { super(Obj.toString()); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
這裡的程式碼雖然短,但是有兩點需要注意的!!!第一點是其繼承了RuntimeException,因為一般我們的業務異常都是執行時異常。第二點,這裡的構造方法呼叫父方法super(Obj.toString());,這就是重寫了LuoErrorCode的toString方法的原因了,如果還不明白,看完後面的你就明白了。
2.3、測試類ExceptionTest.java:
package com.luo.test;
import com.luo.errorcode.LuoErrorCode;
import com.luo.exception.BusinessException;
public class ExceptionTest { public static void main(String args[]) { Object user = null; if(user == null){ throw new BusinessException(LuoErrorCode.NULL_OBJ); } } }
執行結果:
補充一下:在我們實際專案裡面,比如別人呼叫你介面,你可能需要先看他傳過來的物件是不是空的,先判斷如果傳過來的物件為空給有友好的提示”[LUO001]物件為空”,不然後面的程式碼估計會出現空指標異常了。
一般公司都會分裝一個基礎框架,異常分裝是其中一部分,當然他們對異常的分裝肯定比我這個例子複雜多,因此本例僅供參考!
如果懶得copy和paste的話,直接下載工程吧:
http://download.csdn.net/detail/u013142781/9422684
目錄
一、前言
二、例項詳解
轉載: Javaweb異常提示資訊統一處理
一、前言
後臺出現異常如何友好而又高效地回顯到前端呢?直接將一堆的錯誤資訊拋給使用者介面,顯然不合適。
先不考慮程式碼實現,我們希望是這樣的:
(1)如果是頁面跳轉的請求,出現異常了,我們希望跳轉到一個異常顯示頁面,如下:
當然,這裡的介面不夠美觀,但是理論是這樣的。
(2)如果是ajax請求,那麼我們,希望後臺將合理的錯誤顯示返回到ajax的回撥函式裡面,如下:
$.ajax({
type: "post",
url: "<%=request.getContextPath()%>" + "/businessException.json", data: {}, dataType: "json", contentType : "application/json", success: function(data) { if(data.success == false){ alert(data.errorMsg); }else{ alert("請求成功無異常"); } }, error: function(data) { alert("呼叫失敗...."); } });
將回調函式的data.errorMsg打印出來:
下面,我們根據上面的思路我們來看看程式碼的實現。因此本文例項包含了異常自定義分裝,為了無障礙閱讀下文,請猿友移步先看完博主的另外一篇文章:Java異常封裝(自己定義錯誤碼和描述,附原始碼)。
二、例項詳解
本例項使用的環境 eclipse+maven,其中maven只是為了方便引入jar包。
使用的技術:springmvc
在Spring MVC中,所有用於處理在請求對映和請求處理過程中丟擲的異常的類,都要實現HandlerExceptionResolver介面。HandlerExceptionResolver介面有一個方法resolveException,當controller層出現異常之後就會進入到這個方法resolveException。
下面我們直接實現HandlerExceptionResolver介面,程式碼如下:
package com.luo.exceptionresolver;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import com.alibaba.druid.support.json.JSONUtils; import com.luo.exception.BusinessException; import org.springframework.web.servlet.HandlerExceptionResolver; public class MySimpleMappingExceptionResolver implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) { // 判斷是否ajax請求 if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request .getHeader("X-Requested-With") != null && request.getHeader( "X-Requested-With").indexOf("XMLHttpRequest") > -1))) { // 如果不是ajax,JSP格式返回 // 為安全起見,只有業務異常我們對前端可見,否則否則統一歸為系統異常 Map<String, Object> map = new HashMap<String, Object>(); map.put("success", false); if (exception instanceof BusinessException) { map.put("errorMsg", exception.getMessage()); } else { map.put("errorMsg", "系統異常!"); } //這裡需要手動將異常打印出來,由於沒有配置log,實際生產環境應該列印到log裡面 exception.printStackTrace(); //對於非ajax請求,我們都統一跳轉到error.jsp頁面 return new ModelAndView("/error", map); } else { // 如果是ajax請求,JSON格式返回 try { response.setContentType("application/json;charset=UTF-8"); PrintWriter writer = response.getWriter(); Map<String, Object> map = new HashMap<String, Object>(); map.put("success", false); // 為安全起見,只有業務異常我們對前端可見,否則統一歸為系統異常 if (exception instanceof BusinessException) { map.put("errorMsg", exception.getMessage()); } else { map.put("errorMsg", "系統異常!"); } writer.write(JSONUtils.toJSONString(map)); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } }
上面的程式碼,歸結為以下幾點:
(1)判斷如果不是ajax請求,那麼統一跳轉到error.jsp頁面,否則返回json資料。
(2)如果是業務異常,我們直接列印異常資訊,否則,我們統一歸為系統異常,如果不明白這裡的業務異常為何物,請閱讀博主部落格:Java異常封裝(自己定義錯誤碼和描述,附原始碼)。
另外,需要在springmvc配置檔案新增如下配置:
<!-- 框架異常處理Handler -->
<bean id="exceptionResolver" class="com.luo.exceptionresolver.MySimpleMappingExceptionResolver"></bean>
下面我們直接看controller程式碼:
package com.luo.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.luo.errorcode.LuoErrorCode; import com.luo.exception.BusinessException; @Controller public class UserController { @RequestMapping("/index.jhtml") public ModelAndView getIndex(HttpServletRequest request) throws Exception { ModelAndView mav = new ModelAndView("index"); return mav; } @RequestMapping("/exceptionForPageJumps.jhtml") public ModelAndView exceptionForPageJumps(HttpServletRequest request) throws Exception { throw new BusinessException(LuoErrorCode.NULL_OBJ); } @RequestMapping(value="/businessException.json", method=RequestMethod.POST) @ResponseBody public String businessException(HttpServletRequest request) { throw new BusinessException(LuoErrorCode.NULL_OBJ); } @RequestMapping(value="/otherException.json", method=RequestMethod.POST) @ResponseBody public String otherException(HttpServletRequest request) throws Exception { throw new Exception(); } }
關於controller程式碼沒什麼好解釋的,下面我們直接看結果吧:
(1)如果跳轉頁面過程中出現異常,訪問http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml
的結果:
(2)如果ajax請求過程中出現異常,訪問http://localhost:8080/web_exception_project/index.jhtml
,然後,點選業務異常按鈕結果:
點選其他異常按鈕結果:
(3)HandlerExceptionResolver介面並不能處理404錯誤,這種錯誤我們再web.xml裡面新增如下配置:
<!-- 錯誤跳轉頁面 -->
<error-page>
<!-- 路徑不正確 -->
<error-code>404</error-code> <location>/WEB-INF/view/404.jsp</location> </error-page>
然後404.jsp程式碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <taglib uri="http://java.sun.com /jsp/jstl/core" prefix="c" /> <html> <head> <title>錯誤頁面</title> </head> <body> 頁面被黑洞吸走了...... </body> </html>
然後訪問一個不存在的連線:http://localhost:8080/web_exception_project/123456.jhtml
,結果如下:
三、本工程原始碼下載
http://download.csdn.net/detail/u013142781/9424969
目錄
一、前言
二、例項詳解
轉載: Javaweb異常提示資訊統一處理
一、前言
後臺出現異常如何友好而又高效地回顯到前端呢?直接將一堆的錯誤資訊拋給使用者介面,顯然不合適。
先不考慮程式碼實現,我們希望是這樣的:
(1)如果是頁面跳轉的請求,出現異常了,我們希望跳轉到一個異常顯示頁面,如下:
當然,這裡的介面不夠美觀,但是理論是這樣的。
(2)如果是ajax請求,那麼我們,希望後臺將合理的錯誤顯示返回到ajax的回撥函式裡面,如下:
$.ajax({
type: "post",
url: "<%=request.getContextPath()%>" + "/businessException.json", data: {}, dataType: "json", contentType : "application/json", success: function(data) { if(data.success == false){ alert(data.errorMsg); }else{ alert("請求成功無異常"); } }, error: function(data) { alert("呼叫失敗...."); } });
將回調函式的data.errorMsg打印出來:
下面,我們根據上面的思路我們來看看程式碼的實現。因此本文例項包含了異常自定義分裝,為了無障礙閱讀下文,請猿友移步先看完博主的另外一篇文章:Java異常封裝(自己定義錯誤碼和描述,附原始碼)。
二、例項詳解
本例項使用的環境 eclipse+maven,其中maven只是為了方便引入jar包。
使用的技術:springmvc
在Spring MVC中,所有用於處理在請求對映和請求處理過程中丟擲的異常的類,都要實現HandlerExceptionResolver介面。HandlerExceptionResolver介面有一個方法resolveException,當controller層出現異常之後就會進入到這個方法resolveException。
下面我們直接實現HandlerExceptionResolver介面,程式碼如下:
package com.luo.exceptionresolver;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import com.alibaba.druid.support.json.JSONUtils; import com.luo.exception.BusinessException; import org.springframework.web.servlet.HandlerExceptionResolver; public class MySimpleMappingExceptionResolver implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) { // 判斷是否ajax請求 if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request .getHeader("X-Requested-With") != null && request.getHeader( "X-Requested-With").indexOf("XMLHttpRequest") > -1))) { // 如果不是ajax,JSP格式返回 // 為安全起見,只有業務異常我們對前端可見,否則否則統一歸為系統異常 Map<String, Object> map = new HashMap<String, Object>(); map.put("success", false); if (exception instanceof BusinessException) { map.put("errorMsg", exception.getMessage()); } else { map.put("errorMsg", "系統異常!"); } //這裡需要手動將異常打印出來,由於沒有配置log,實際生產環境應該列印到log裡面 exception.printStackTrace(); //對於非ajax請求,我們都統一跳轉到error.jsp頁面 return new ModelAndView("/error", map); } else { // 如果是ajax請求,JSON格式返回 try { response.setContentType("application/json;charset=UTF-8"); PrintWriter writer = response.getWriter(); Map<String, Object> map = new HashMap<String, Object>(); map.put("success", false); // 為安全起見,只有業務異常我們對前端可見,否則統一歸為系統異常 if (exception instanceof BusinessException) { map.put("errorMsg", exception.getMessage()); } else { map.put("errorMsg", "系統異常!"); } writer.write(JSONUtils.toJSONString(map)); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } }
上面的程式碼,歸結為以下幾點:
(1)判斷如果不是ajax請求,那麼統一跳轉到error.jsp頁面,否則返回json資料。
(2)如果是業務異常,我們直接列印異常資訊,否則,我們統一歸為系統異常,如果不明白這裡的業務異常為何物,請閱讀博主部落格:Java異常封裝(自己定義錯誤碼和描述,附原始碼)。
另外,需要在springmvc配置檔案新增如下配置:
<!-- 框架異常處理Handler -->
<bean id="exceptionResolver" class="com.luo.exceptionresolver.MySimpleMappingExceptionResolver"></bean>
下面我們直接看controller程式碼:
package com.luo.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.luo.errorcode.LuoErrorCode; import com.luo.exception.BusinessException; @Controller public class UserController { @RequestMapping("/index.jhtml") public ModelAndView getIndex(HttpServletRequest request) throws Exception { ModelAndView mav = new ModelAndView("index"); return mav; } @RequestMapping("/exceptionForPageJumps.jhtml") public ModelAndView exceptionForPageJumps(HttpServletRequest request) throws Exception { throw new BusinessException(LuoErrorCode.NULL_OBJ); } @RequestMapping(value="/businessException.json", method=RequestMethod.POST) @ResponseBody public String businessException(HttpServletRequest request) { throw new BusinessException(LuoErrorCode.NULL_OBJ); } @RequestMapping(value="/otherException.json", method=RequestMethod.POST) @ResponseBody public String otherException(HttpServletRequest request) throws Exception { throw new Exception(); } }
關於controller程式碼沒什麼好解釋的,下面我們直接看結果吧:
(1)如果跳轉頁面過程中出現異常,訪問http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml
的結果:
(2)如果ajax請求過程中出現異常,訪問http://localhost:8080/web_exception_project/index.jhtml
,然後,點選業務異常按鈕結果:
點選其他異常按鈕結果:
(3)HandlerExceptionResolver介面並不能處理404錯誤,這種錯誤我們再web.xml裡面新增如下配置:
<!-- 錯誤跳轉頁面 -->
<error-page>
<!-- 路徑不正確 -->
<error-code>404</error-code> <location>/WEB-INF/view/404.jsp</location> </error-page>
然後404.jsp程式碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <taglib uri="http://java.sun.com /jsp/jstl/core" prefix="c" /> <html> <head> <title>錯誤頁面</title> </head> <body> 頁面被黑洞吸走了...... </body> </html>
然後訪問一個不存在的連線:http://localhost:8080/web_exception_project/123456.jhtml
,結果如下:
三、本工程原始碼下載
http://download.csdn.net/detail/u013142781/9424969