1、Spring controller层异常的统一处理
该方法是在 https://my.oschina.net/u/3136014/blog/904643 上的某一方面扩展,使其在异常(包括RuntimeException和各种自定义异常)的抓取与前端显示上的统一。
1.1 spring-mvc.xml:配置xml
此处class为该ExceptionAspect.java的路径
<!-- 异常捕获aop -->
<bean id="exceptionHandler" class="*.*.ExceptionAspect" />
1.2 ExceptionAspect.java:
这里取了个巧:Pointcut切点选择了所有被@RequestMapping注解修饰的方法,按照代码规范,所有被注解修饰的方法均在controller里。
利用aop的around(环绕),对异常进行抓取并进行相应的处理
同时判断其是否为ajax请求,同时可根据抓取的异常里的e.getMessage()来接收自定义异常的报错内容,使其交互更符合实际需求。
/**
* @Description: 切面:统一的异常处理
*/
@Aspect
@Component
public class ExceptionAspect extends BaseAction {
@Autowired
private HttpServletRequest request;
//日志相关的service层,将相关数据以日志形式保存下来
@Resource
private SysLogService sysLogService;
// Controller层切点
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
//@annotation用于匹配当前执行方法持有指定注解的方法;
public void exceptionAspect() {
}
@Around("exceptionAspect()")
public Object around(ProceedingJoinPoint joinPoint){
Object object = null;
Result result = new Result();
try {
object = joinPoint.proceed();
return object;
} catch (Exception e) {
e.printStackTrace();
String message = e.getMessage();
if(StringUtils.isNotBlank(message)){
if(message.length() > 100){
message = message.substring(0,100);
}
result.setMsg(message);
}else {
result.setMsg("" + e.getClass());
}
sysLogService.saveByJoinPoint(joinPoint,SecurityConstants.OPER_LOG_STATUS.OPER_LOG_STATUS_FAIL_4ENUM.getValue(),result.getMsg());
} catch (Throwable throwable) {
throwable.printStackTrace();
}
//request.getHeader("x-requested-with")为 null,则为传统同步请求,为 XMLHttpRequest,则为 Ajax 异步请求。
if("XMLHttpRequest".equals(request.getHeader("x-requested-with"))){
return result;//是ajax请求
} else {
Map<String,Object> context = new HashMap<String,Object>();
context.put("result",result);
JSONObject jsonObject = coverJson("/test/common/page/error.vm",context);
ModelAndView mav = new ModelAndView("/common/page/error");
mav.addAllObjects(jsonObject);
return mav;
}
}
}
1.3 实际效果
所有被@RequestMapping注解修饰的方法(按照代码规范,均在controller层中),一旦抛出异常,均会被该ExceptionAspect.java抓取到。若异常已被方法自身try catch到,则不会被抓取。同时可将Exception的报错类型和报错信息以开发者需要的形式或保存到日志中,或展示在前端页面上。