在Web应用程序中,由于用户的操作不当,或者程序本身问题,有大量需要处理的异常。有些异常是我们已知的,并且做了用户友好提示暴露给用户,有些是我们难以发现的。这就需要有一个机制,集中去处理系统全局异常,并转换为对用户友好的信息。
本文主要使用@ExceptionHandler
和@ControllerAdvice
注解来处理全局异常问题。
@ExceptionHandler: 统一处理某类异常,减少代码重复率和复杂度。
@ControllerAdvice: 该注解作用对象为TYPE,包括类、接口和枚举等,在运行时有效,并且可以通过Spring扫描为bean组件。其可以包含由@ExceptionHandler
、@InitBinder
和@ModelAttribute
标注的方法,可以处理多个Controller类,这样所有控制器的异常可以在一个地方进行处理。
下面是demo示例:
- 定义一个自定义异常
public class GeneralException extends RuntimeException {
private static final long serialVersionUID = -3196445791229946673L;
// 自定义错误码
private ErrorCode exceptionType = ErrorCode.OTHER;
public GeneralException(ErrorCode exceptionType) {
super();
this.exceptionType = exceptionType;
}
public GeneralException(ErrorCode exceptionType, String message) {
super(message);
this.exceptionType = exceptionType;
}
public GeneralException() {
super();
this.exceptionType = ErrorCode.OTHER;
}
public ErrorCode getExceptionType() {
return this.exceptionType;
}
@Override
public String getMessage() {
return StringUtils.isEmpty(super.getMessage()) ? this.exceptionType.toString()
: this.exceptionType.toString() + ':' + super.getMessage();
}
.........
}
- 利用@ControllerAdvice定义全局异常处理类
@ControllerAdvice
public class ExceptionHandler1 {
// 处理自定义异常
@ExceptionHandler(GeneralException.class)
public ModelAndView generalExceptionHnadler(GeneralException exception) {
ModelAndView modelAndView = new ModelAndView("error/error") ;
modelAndView.addObject("errCode", exception.getExceptionType());
modelAndView.addObject("errMsg", exception.getSimpleMessage());
return modelAndView;
}
// 处理其他异常
@ExceptionHandler(Exception.class) // 可以直接写@EceptionHandler,IOExeption继承于Exception
public ModelAndView allExceptionHandler(Exception exception) {
ModelAndView modelAndView = new ModelAndView("error/error");
modelAndView.addObject("errMsg", "系统内部错误");
return modelAndView;
}
}
3.在Controller方法中抛出异常
@RequestMapping("test")
public Object test() throws Exception {
if ("XXXX".equals(type)) {
// 由customGenericExceptionHnadler处理
throw new GeneralException(ErrorCode.INTERNAL_ERROR, "XX错误");
}
if ("YYYY".equals(type)) {
// 由handleAllException处理
throw new IOException();
}
// 如果业务操作有异常,由handleAllException处理
}