SpringBoot自定义异常处理
当后端发生异常,前端只知道发生错误,但是不了解错误产生的原因,这里就用到了自定义异常,而且自定义异常也可以帮助事务回滚(Soring事务只有运行时异常才可回滚)
1、自定义异常类继承RuntimeException(运行时异常)
public class MyException extends RuntimeException{
public MyException(String message){
super(message);
}
}
2、自定义JSON返回数据
public class Resp<T> {
@ApiModelProperty(name = "code",value = "响应状态码")
private Integer code;
@ApiModelProperty(name = "msg",value = "提示消息")
private String msg;
@ApiModelProperty(name = "count",value = "总条数")
private Long count;
@ApiModelProperty(name = "data",value = "响应数据")
private T data;
public Resp(Integer code, String msg, Long count,T data) {
this.code = code;
this.msg = msg;
this.count=count;
this.data = data;
}
public Resp() {
}
public Resp(T data) {
this.data = data;
}
public static<T> Resp<T> ok(T data){
Resp<T> resp = new Resp<T>(data);
resp.setCode(0);//操作成功
resp.setMsg("success");
return resp;
}
public static<T> Resp<T> fail(String data){
Resp<T> resp = new Resp<T>();
resp.setCode(1);//操作失败
resp.setMsg(data);
return resp;
}
public static<T> Resp<T> pageok(Long count,T data){
Resp<T> resp = new Resp<T>(data);
resp.setCode(0);//操作成功
resp.setMsg("success");
resp.setCount(count);
return resp;
}
public Resp<T> msg(String msg){
this.setMsg(msg);
return this;
}
public Resp<T> code(Integer code){
this.setCode(code);
return this;
}
public Resp<T> count(Long count){
this.setCount(count);
return this;
}
}
3、全局异常处理
/**
* 处理异常类
*/
@ControllerAdvice//(该注解只能处理controller里的自定义异常)
public class GlobalMyExceptionHandler {
@ExceptionHandler(value = MyException.class)
@ResponseBody
public Resp handlerException(MyException e){
return Resp.fail(e.getMsg());
}
}
使用和效果
找到任意你想要抛出异常的地方
throw new MyException("抛出异常的原因");
返回的JSON数据
{
"code": 1,
"msg": "抛出异常的原因",
"count": null,
"data": null
}
重点来了
上面提到的全局异常@ControllerAdvice只能处理Controller层的异常。那么如果filter里的异常呢,它能不能处理呢,答案是不能。我们需要写一个类去继承BasicErrorController
那么怎样才能处理filter里的异常呢。还需配置如下
自定义ErrorController类继承BasicErrorController类
@RestController
public class ErrorController extends BasicErrorController {
public ErrorController() {
super(new DefaultErrorAttributes(), new ErrorProperties());
}
@RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> errorAttributes = getErrorAttributes(request, ErrorAttributeOptions.of(ErrorAttributeOptions.Include.EXCEPTION,ErrorAttributeOptions.Include.MESSAGE,ErrorAttributeOptions.Include.STACK_TRACE,ErrorAttributeOptions.Include.BINDING_ERRORS));
HttpStatus status = getStatus(request);
// 获取错误信息
String code = errorAttributes.get("status").toString();
String message = errorAttributes.get("message").toString();
ApiErrorResult apiErrorResult = new ApiErrorResult(false,code,message);
return new ResponseEntity<>(apiErrorResult,status);
}
}
配置类
public class ApiErrorResult extends LinkedHashMap<String,Object> {
private static final String SUCCESS_KEY = "success";
private static final String CODE_KEY = "code";
private static final String MESSAGE_KEY = "message";
public ApiErrorResult(boolean success, String code, String message) {
this.put(SUCCESS_KEY,success);
this.put(CODE_KEY,code);
this.put(MESSAGE_KEY,message);
}
}
这两步配置好了之后,filte里自定义的异常就可以处理啦。是不是很棒呢!