当 web 程序发生了异常,往往会在客户端直接显示 “Whitelabel Error Page” 页面,十分的不美观。因此,每一个 web 程序都需要通过一个统一的全局异常处理方案来保证客户端能够收到友好的提示。
1 Spring Boot 默认的异常处理机制
当浏览器客户端请求一个不存在的页面或服务端处理发生异常时,Spring Boot 默认会响应一个 html 文档内容,称作“Whitelabel Error Page”。
我们先写一个控制器,故意让它产生一个错误
@Controller
public class IndexController {
@RequestMapping("index")
public String index(){
int i = 1/0;
return "index" ;
}
}
然后我们打开浏览器,发现页面如下:
2 通过 @ControllerAdvice 注解来处理异常
我们可以使用 @ControllerAdvice 注解和 @ExceptionHandler 注解来实现对指定异常的特殊处理。如果我们需要局部异常处理,使用 @Controller + @ExceptionHandler 即可,若需要全局异常处理,则应该使用 @ControllerAdvice + @ExceptionHandler。
局部异常处理
局部异常处理需要使用 @ExceptionHandler 注解,注解到类的方法上,当此注解里定义的异常抛出时,此方法会被执行。如果 @ExceptionHandler 所在的类是 @Controller ,则此方法只作用在此类。如果 @ExceptionHandler 所在的类带有 @ControllerAdvice 注解,则此方法会作用在全局。
举个例子,我们修改下上面使用过的控制器,使用 @ExceptionHandler 来捕捉异常
@Controller
public class IndexController {
@RequestMapping("index")
public String index(){
int i = 1/0;
return "index" ;
}
@ExceptionHandler(Exception.class)
@ResponseBody
public String exHandler(Exception e){
if(e instanceof ArithmeticException){
return "/ by zero";
}
return "others";
}
}
然后我们再次打开浏览器
发现该异常已被 @ExceptionHandler 处理,且将错误信息输出到客户端中。
全局异常处理
@ControllerAdvice 注解新增于 spring 3.2。
我们需要注意,唯有进入 Controller 层的错误才会由 @ControllerAdvice 处理,拦截器抛出的错误以及访问错误地址的情况将会由 SpringBoot 默认的异常处理机制处理。
我们创建一个全局异常处理类
@ControllerAdvice
public class ExceptionAdvice {
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map<String,Object> exceptionHandler(Exception ex){
Map<String,Object> map = new HashMap<String,Object>();
map.put("message", ex.getMessage());
map.put("localizedmessage", ex.getLocalizedMessage());
map.put("class", ex.getClass());
map.put("stacktrace", ex.getStackTrace());
map.put("suppressed", ex.getSuppressed());
return map;
}
}
当控制器抛出异常时,在客户端中显示
本文只是简单地介绍了 Spring Boot 中的全局异常处理方案,若有不足之处希望大家能在评论中指出,感谢各位的观看。