Spring对异常统一处理的方式有两种:
- 使用 HandlerExceptionResolver 接口,并且 Spring 已经提供默认的实现类 SimpleMappingExceptionResolver。
- 使用@ExceptionHandler注解实现异常处理
一、基于 HandlerExceptionResolver 接口的方式
使用这种方式只需要实现 resolveException 方法,该方法返回一个 ModelAndView 对象,在方法内部对异常的类型进行判断,然后返回合适的 ModelAndView 对象,如果该方法返回了 null,则 Spring 会继续寻找其他的实现了 HandlerExceptionResolver 接口的 Bean。换句话说,Spring 会搜索所有注册在其环境中的实现了 HandlerExceptionResolver 接口的 Bean,逐个执行,直到返回了一个 ModelAndView 对象。
@Component
public class CustomExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) {
if(exception instanceof IOException){
return new ModelAndView("ioexp");
}else if(exception instanceof SQLException){
return new ModelAndView("sqlexp");
}
return null;
}
}
注意:这个类必须声明到 Spring 配置文件中,或者使用 @Component 标签,让 Spring 管理它。同时 Spring 也提供默认的实现类 SimpleMappingExceptionResolver,需要使用时只需要使用注入到 Spring 配置文件进行声明即可。自定义实现类与默认的实现类,可同时使用。
二、使用@ExceptionHandler
提示:当一个Controller中有方法加了@ExceptionHandler之后,这个Controller其他方法中没有捕获的异常就会以参数的形式传入加了@ExceptionHandler注解的那个方法中。
使用加强Controller做全局异常处理。
所谓加强Controller就是@ControllerAdvice注解,有这个注解的类中的方法的某些注解会应用到所有的Controller里,其中就包括@ExceptionHandler注解。
于是可以写一个全局的异常处理类:
@ControllerAdvice
public class GlobalExceptionHandler {
//处理自定义的异常
@ExceptionHandler(BusinessException.class)
@ResponseBody
public Object customHandler(BusinessException e) {
e.printStackTrace();
return new ResponseResultDto.Builder<String>().setCode(e.getCode()).setMessage(e.getMessage()).builder();
}
//其他未处理的异常
@ExceptionHandler(Exception.class)
@ResponseBody
public Object exceptionHandler(Exception e) {
e.printStackTrace();
return new ResponseResultDto.Builder<String>().setCode(StatusEnum.FAILURE.getCode()).setMessage(e.getMessage()).builder();
}
}
这个类中只处理了两个异常,但是已经满足了大部分需要,如果还有需要特殊处理的地方,可以再加上处理的方法就行了,推荐使用这种处理方式。