在java中获取到一个exception后有时需要获取该异常的根异常,实现方法有多重,本文介绍两种方式:一种是逐一判断该异常属于哪一个异常的实例,另一个是遍历找到最终抛出异常的类型。
1、判断异常实例类型
java中可以使用instanceof判断该对象是否是某一个类的实例,通过该方法可以判断异常的类型并调用相应的处理方法。
demo如下,在Java web中使用instanceof判断异常类型并调用不同的方法进行处理
package com.landsem.update.base.exception.handler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import com.landsem.update.base.exception.ActionUnSupportException;
public class ExceptionDispatcher implements HandlerExceptionResolver {
protected static Logger logger = Logger.getLogger(ExceptionDispatcher.class);
@Override
public ModelAndView resolveException(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3) {
//action unSupport exception.自定义的异常
if (arg3 instanceof ActionUnSupportException) {
logger.error("ActionUnSupportException exception.");
arg3.printStackTrace();
}
//DataIntegrityViolationException exception.数据库抛出的异常
else if (arg3 instanceof DataIntegrityViolationException) {
logger.error("DataIntegrityViolationException");
arg3.printStackTrace();
}
//base exception.根异常
else if (arg3 instanceof Exception) {
logger.error("unknown exception.");
arg3.printStackTrace();
}
return null;
}
}
2、遍历获取根异常并通过反射机制调用处理方法
通过判断异常的getCause是否为空判断是否为最终的异常抛出类。
参考如下demo,java web(配置略,如需查看配置方法请参考http://www.voidcn.com/article/p-txulnyff-qp.html)中实现异常捕获并根据最终的异常类型通过反射机制调用异常类型+Handler的类的handlerException方法进行处理进行异常处理。
package com.landsem.update.base.exception.handler;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
public class ExceptionDispatcher implements HandlerExceptionResolver {
protected static Logger logger = Logger
.getLogger(ExceptionDispatcher.class);
@Override
public ModelAndView resolveException(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3) {
//
if (null != arg3) {
Throwable tb = findRootExceptionThrowable(arg3);
if (null != tb) {
String basePackageName = this.getClass().getPackage().getName();
String exceptionBaseName = tb.getClass().getName();
String handlerClassName = new StringBuffer()
.append(basePackageName)
.append(exceptionBaseName.substring(exceptionBaseName
.lastIndexOf("."))).append("Handler").toString();
logger.info(handlerClassName);
try {
Class> cls = Class.forName(handlerClassName);
if (null != cls) {
Method m = cls.getDeclaredMethod("handlerException",
new Class[] { HttpServletRequest.class,
HttpServletResponse.class, Object.class,
Throwable.class });
if (null != m) {
return (ModelAndView) m.invoke(cls.newInstance(), arg0,
arg1, arg2, tb);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
/**
* find root exception throwable.
*
* @param e
* @return
*/
protected Throwable findRootExceptionThrowable(Exception e) {
/*
* Throwable tmp = e.getCause(); while (null != tmp &&
* !(tmp.getClass().getName().equals(tmp.getCause().getClass()
* .getName()))) { tmp = tmp.getCause(); } return tmp;
*/
Throwable rootCause = e;
while (rootCause.getCause() != null) {
rootCause = rootCause.getCause();
}
return rootCause;
}
}
异常处理类实现如下接口方便通过反射调用到处理方法:
package com.landsem.update.base.exception.handler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
public interface IExceptionHandler {
public ModelAndView handlerException(HttpServletRequest request,
HttpServletResponse response, Object arg,Throwable tb);
}
如下为一个简单的ParamsFormatErrorExceptionHandler实现,当抛出自定义异常ParamsFormatErrorException时被反射调用。
package com.landsem.update.base.exception.handler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
public class ParamsFormatErrorExceptionHandler implements IExceptionHandler{
protected static Logger logger = Logger
.getLogger(ExceptionDispatcher.class);
@Override
public ModelAndView handlerException(HttpServletRequest request,
HttpServletResponse response, Object arg, Throwable tb) {
logger.error("request format error!");
return null;
}
}