前言
本文介绍spring MVC的自定义异常处理,即在Controller中抛出自定义的异常时,客户端收到更友好的JSON格式的提示,而不是常见的报错页面,方便移动端的处理。
注解介绍
@ControllerAdvice注解,是spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强,可以用来通过结合注解@ExceptionHanlder, 来定义具体的异常处理, 以及返回的结果。
@ControllerAdvice
使@ControllerAdvice注解生效有两种方式:
- 1.额外添加@EnableWebMvc注解
@EnableWebMvc
@ControllerAdvice
public class BaseController {
@ExceptionHandler()
public void handleException(Exception e) {
System.out.println("rrrrrrrrrrrrr");
}
}
- 2.spring-mvc.xml文件中添加注解驱动器
<mvc:annotation-driven />
使用@ExceptionHandler注解可以指定spring捕获到所有抛出的CustomException异常,由这个被注解的方法处理
@ExceptionHandler(value = CustomException.class)
使用@ResponseBody注解可以使Spring自动把要返回的对象转化成json文本写入到响应体中
@ResponseBody
Sample展示
创建一个GlobalExceptionHandler.java类实现全局异常处理,该类会自动拦截异常然后做相应的处理
这边需要注意的是, @ExceptionHandler可定义多个, 当多个匹配时, 按编写最早的处理函数优先处理. 这边就像try/catch那种常见的情况了, 既顺序敏感。最佳实践, 需要把处于顶层的异常类搁置到代码最尾端
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = CustomException.class)
@ResponseBody
public ResponseWrapper handle(CustomException ex) {
String message = ex.getMessage();
return ex.getErrorWrapper(0, message);
}
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseWrapper handle(Exception ex) {
String message = ex.getMessage();
System.out.println("GlobalExceptionHandler: " + message);
return ResponseWrapper.occurException(0, message);
}
}
返回值封装类,该类就是最后传到用户面前的最后一个类,正常时返回正常json文本,错误时返回相应的code和message异常信息
public class ResponseWrapper<T> implements Serializable {
private Integer code = 1;
private String errorMsg = "成功";
private T requestData;
public ResponseWrapper() {
}
private ResponseWrapper(Integer code, String errorMsg) {
this.code = code;
this.errorMsg = errorMsg;
}
public static ResponseWrapper occurException(Integer code, String errorMsg) {
return new ResponseWrapper(code, errorMsg);
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public T getRequestData() {
return requestData;
}
public void setRequestData(T requestData) {
this.requestData = requestData;
}
}
CustomException类起到一个桥梁作用,遇到异常时传不同的code和message进去,然后封装成ResponseWrapper对象,剩下的就是如何优雅实现的问题了,如下是CustomException的实现:
public class CustomException extends Exception {
//异常信息
private String message;
private Integer code;
public CustomException(String message) {
super(message);
this.message = message;
}
public ResponseWrapper getErrorWrapper(Integer code, String message) {
return ResponseWrapper.occurException(code, message);
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}