Spring Boot 默认提供了程序出错的结果映射路径/error(见:Spring Boot 错误页面)。其内部是通过判断请求头中的Accept的内容是否为text/html来区分请求是来自客户端浏览器(浏览器通常默认自动发送请求头内容Accept:text/html)还是客户端接口的调用,以此来决定返回页面视图还是 JSON 消息内容。

1. 自定义异常处理

使用@ControllerAdvice注解可以对已知的Controller中抛出的异常进行捕获并处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(BusinessHtmlException.class)
public ModelAndView handleHtmlException(Exception e) {
logger.error("「捕捉到异常」:", e);
ModelAndView modelAndView = new ModelAndView("error/general");
modelAndView.addObject("message", e.getMessage());
return modelAndView;
}
@ExceptionHandler({
BusinessJsonException.class,
IllegalArgumentJsonException.class
})
public ResponseEntity<?> handleJsonException(Exception e) {
logger.error("「捕捉到异常」:", e);
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
return new ResponseEntity<>(new HttpResponseBody(status.value(), e.getMessage(), null), status);
}
}

1.1 @ExceptionHandler

该注解用于标注处理方法处理哪些特定的异常。被该注解标注的方法可以有以下任意顺序的参数类型:

  • Throwable、Exception 等异常对象;
  • ServletRequest、HttpServletRequest、ServletResponse、HttpServletResponse;
  • HttpSession 等会话对象;
  • org.springframework.web.context.request.WebRequest;
  • java.util.Locale;
  • java.io.InputStream、java.io.Reader;
  • java.io.OutputStream、java.io.Writer;
  • org.springframework.ui.Model;

并且被该注解标注的方法可以有以下的返回值类型可选:

  • ModelAndView;
  • org.springframework.ui.Model;
  • java.util.Map;
  • org.springframework.web.servlet.View;
  • @ResponseBody 注解标注的任意对象;
  • HttpEntity<?> or ResponseEntity<?>;
  • void;

以上罗列的不完全,更加详细的信息可参考:Spring ExceptionHandler

1.2 @ResponseStatus

@ExceptionHandler 注释可以与 @ResponseStatus 结合起来,以定义 HTTP 响应的状态码值。

以下为涉及本示例的其余代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class HttpResponseBody {
private int code;
private String errmsg;
private Object data;
public HttpResponseBody(int code, String errmsg, Object data) {
this.code = code;
this.data = data;
this.errmsg = errmsg;
}
// getters and setters
}
1
2
3
4
5
6
7
public class BusinessHtmlException extends RuntimeException {
public BusinessHtmlException(String message) {
super(message);
}
}
1
2
3
4
5
6
7
public class BusinessJsonException extends RuntimeException {
public BusinessJsonException(String message) {
super(message);
}
}
1
2
3
4
5
6
7
public class IllegalArgumentJsonException extends RuntimeException {
public IllegalArgumentJsonException(String message) {
super(message);
}
}

示例项目开发环境:Java-8、Maven-3、IntelliJ IDEA-2017、Spring Boot-1.5.2.RELEASE
完整示例项目链接:spring-boot-exception-handler-sample
参考文档文献链接:http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#boot-features-error-handling