Spring Aop 统一异常管理共分为两步:
1、编写统一异常捕获并完成异常处理类
2、修改spring的配置文件使异常捕获类生效。
具体步骤如下:
1、异常捕获类代码:
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import com.taole.toolkit.util.DateStyle;
import com.taole.toolkit.util.DateUtil;
@Aspect
public class ExceptionAspect {
private Logger logger = LoggerFactory.getLogger("exception");
// 切入点表达式按需配置
@Pointcut("execution(* com.test.exception.manager.*.*(..))")
private void pointcutMethod() {
}
@AfterThrowing(value = "pointcutMethod()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Throwable e) {
logger.error("Exception happened in time: " + DateUtil.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
logger.error("Exception happened in method: " + getMethodNameAndArgs(joinPoint));
logger.error("Exception class: " + e.getClass().getName());
logger.error("Exception message():" + e.getMessage());
// 在这里判断异常,根据不同的异常返回错误。
if (e.getClass().equals(DataAccessException.class)) {
throw new BusinessException("数据库操作失败!");
} else if (e.getClass().toString().equals(NullPointerException.class.toString())) {
throw new BusinessException("调用了未经初始化的对象或者是不存在的对象!");
} else if (e.getClass().equals(IOException.class)) {
throw new BusinessException("IO异常!");
} else if (e.getClass().equals(ClassNotFoundException.class)) {
throw new BusinessException("指定的类不存在!");
} else if (e.getClass().equals(ArithmeticException.class)) {
throw new BusinessException("数学运算异常!");
} else if (e.getClass().equals(ArrayIndexOutOfBoundsException.class)) {
throw new BusinessException("数组下标越界!");
} else if (e.getClass().equals(IllegalArgumentException.class)) {
throw new BusinessException("方法的参数错误!");
} else if (e.getClass().equals(ClassCastException.class)) {
throw new BusinessException("类型强制转换错误!");
} else if (e.getClass().equals(SecurityException.class)) {
throw new BusinessException("违背安全原则异常!");
} else if (e.getClass().equals(SQLException.class)) {
throw new BusinessException("操作数据库异常!");
} else if (e.getClass().equals(NoSuchMethodError.class)) {
throw new BusinessException("方法末找到异常!");
} else if (e.getClass().equals(InternalError.class)) {
throw new BusinessException("Java虚拟机发生了内部错误");
} else {
throw new BusinessException("程序内部错误,操作失败!" + e.getMessage());
}
}
/**
* 获取方法名和参数
* @author lyl
* @param joinPoint
* @return
*/
private String getMethodNameAndArgs(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
StringBuffer sb = new StringBuffer("请求方法:");
sb.append(joinPoint.getTarget().getClass().getName() + "."
+ joinPoint.getSignature().getName() + "(");
for (int i = 0; i < args.length; i++) {
sb.append("arg[" + i + "]: " + args[i] + ",");
}
if (args.length > 0) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append(")");
return sb.toString();
}
}
编写友好信息提示类:
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 3152616724785436891L;
public BusinessException(String frdMessage) {
super(createFriendlyErrMsg(frdMessage));
}
public BusinessException(Throwable throwable) {
super(throwable);
}
public BusinessException(Throwable throwable, String frdMessage) {
super(throwable);
}
private static String createFriendlyErrMsg(String msgBody) {
String prefixStr = "抱歉,";
String suffixStr = " 请稍后再试或与管理员联系!";
StringBuffer friendlyErrMsg = new StringBuffer("");
friendlyErrMsg.append(prefixStr);
friendlyErrMsg.append(msgBody);
friendlyErrMsg.append(suffixStr);
return friendlyErrMsg.toString();
}
}
2、修改spring的配置文件:
如果没有引入spring aop先添加aop引用:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd" default-lazy-init="false">
<!-- 配置切面的类 -->
<bean id="exceptionAspect" class="com.test.exception.ExceptionAspect"/>
<!-- 配置成注解方式寻找要被代理的对象 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
至此统一异常管理的代码就写完了。
编写过程中遇到的问题:
1、配置的扫描包(com.test.exception.manager)不起作用,
解决方法:在spring的配置文件中添加扫描即可
<context:component-scan base-package="com.jiakang.miai.account.manager" />