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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章