J2EE項目中統一異常處理

J2EE項目中統一異常處理


一. 說明

Spring+ Spring MVC + hibernate項目比較流行,在MVC三層結構中不可避免會有異常出現,若對於每個過程中的異常進行單獨處理,那麼代碼的耦合度太高,不便於維護,所以必然需要解耦,分離出來,因此就出現了異常統一處理這一說法。

Spring MVC處理異常的方式大致有三種:

1.使用Spring MVC提供的簡單異常處理SimpleMappingExceptionResolver

2.實現Spring的異常處理接口HandlerExceptionResolver自定義自己的異常處理器

3.使用@ExceptionHandler註解實現異常處理

以下主要說明第二種處理方式。

 

二. 自定義異常處理器

先需要新建一個類(名叫ExceptionHandler)實現HandlerExceptionResolver的接口中resolveException方法:

 

public ModelAndViewresolveException

(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)

在這裏可以直接獲取到異常 ex,爲了更好的處理異常後返回提示信息,我們通過對異常類進行匹配:

if(ex.getClass().equals(NullPointerException.class)

然後向modelAndView寫入相關信息:

StringBuffer  errormsg = new StringBuffer(“調用了未經初始化的對象或者是不存在的對象”);

modelAndView.addObject("ex",new Exception(errormsg+""));

最後重定向至錯誤頁面即可看到錯誤信息:

modelAndView.setViewName("exception/error");

 

但是僅僅如此是不行的,因爲有的時候提示信息範圍太大:

如:添加的字段過長導致報錯,通過ex.getMessage()獲取到的信息爲->

錯誤原因:org.hibernate.exception.GenericJDBCException:could not execute statement]

從這裏基本看不出是字段過長導致的,

於是重點來了:通過

Throwable cause =ex.getCause(); 進一步查看導致異常的原因

如上述的異常可以進行如下處理:

通過 if(ex.getClass().equals(PersistenceException.class))

將異常歸類爲 PersistenceException異常,再通過cause.getClass()對異常再進行細分:

If(cause.getClass().equals(GenericJDBCException.class))

最後通過:

((org.hibernate.exception.GenericJDBCException)cause).getSQLException().getMessage()

獲取異常的原因:會發現爲:

[錯誤原因:ORA-12899: 列 "SCOTT"."STUDENT"."NAME" 的值太大 (實際值: 102, 最大值: 5)]

 

三. 讓spring 管理到自定義的異常類

在spring mvc的配置文件中加入:

<bean id="exceptionResolver"class="com.nuohy.utils.exception.ExceptionHandler"/>

即可


四.  補充 !!!  獲取最終導致異常的原因: 

	/**
	 * 獲取具體信息
	 * @param cause
	 * @return
	 */
	public String getExCause(Exception ex){
		String recontent = null;
		
		/**
		 * 針對處理大部分數據庫異常
		 */
		Throwable oldcause = ex.getCause();
		if(oldcause==null){
			recontent = ex.getMessage();
		}else{
			while(true){
				Throwable cau = oldcause.getCause();
				if(cau==null){
					if(oldcause.getMessage()==null){
						recontent = ex.getMessage();
						break;
					}else{
						recontent = oldcause.getMessage();
						break;
					}
				}else{
					oldcause = oldcause.getCause();
				}
			}
		}
		
		
		if(recontent==null){
			String errormsg = ex.getMessage();
			
			if(ex.getClass().equals(DataAccessException.class)){
				
				recontent = "發生DataAccessException異常";
				
			}else if(ex.getClass().equals(NullPointerException.class)){
				
				recontent = "調用了未經初始化的對象或者是不存在的對象";
				
			}else if(ex.getClass().equals(IOException.class)){
				
				recontent = "IO異常";
				
			}else if(ex.getClass().equals(ClassNotFoundException.class)){
				
				recontent = "指定的類不存在";

			}else if(ex.getClass().equals(ArithmeticException.class)){
				
				recontent = "數學運算異常";

			}else if(ex.getClass().equals(ArrayIndexOutOfBoundsException.class)){
				
				recontent = "數組下標越界";

			}else if(ex.getClass().equals(IllegalArgumentException.class)){
				
				recontent = "方法的參數錯誤";
				
			}else if(ex.getClass().equals(ClassCastException.class)){
				
				recontent = "類型強制轉換錯誤";
				
			}else if(ex.getClass().equals(SecurityException.class)){
				
				recontent = "違背了安全原則";
				
			}else if(ex.getClass().equals(SQLException.class)){
				
				recontent = "操作數據庫異常";
				
			}else if(ex.getClass().equals(NoSuchMethodError.class)){
				
				recontent = "方法末找到異常";
				
			}else if(ex.getClass().equals(InternalError.class)){
				
				recontent = "Java虛擬機發生了內部錯誤,[錯誤信息:" + ex.getMessage() + "]";
				
			}else if(ex.getClass().equals(UnauthorizedException.class)){
				
				recontent = "您尚未擁有權限訪問該資源,[錯誤信息:" + ex.getMessage() + "]";
				
			}else{
				recontent = "未知錯誤!";
			}
			
			recontent += errormsg!=null?",[錯誤原因:" + errormsg + "]":"";
		}
		
		return recontent;
		
	}



 

附上源碼下載地址:http://download.csdn.net/detail/qq_27063119/9732953


 

 

發佈了48 篇原創文章 · 獲贊 74 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章