异常处理在项目中还是比较重要的,springboot 中的异常有些类似于springmvc,熟悉springmvc的朋友就不会那么陌生了。为什么我们在项目中需要做全局异常处理昵,实际是可以在每一个contoller中的每一个方法中加入try catch,实现对异常的处理,但是这样写就会变焦麻烦,代码也会比较冗余,所以使用全局异常处理,在service中直接抛出异常就可以了,非常的简单。
1.优缺点
- 优点:将 Controller 层的异常和数据校验的异常进行统一处理,减少模板代码,减少编码量,提升扩展性和可维护性。
- 缺点:只能处理 Controller 层未捕获(往外抛)的异常,对于 Interceptor(拦截器)层的异常,Spring 框架层的异常,就无能为力了。
- 对于 Interceptor(拦截器)或者spring框架等其他的异常try catch 返回自己定义的异常类。
2.首先主要讲两个注解
@ControllerAdvice 和 @ExceptionHandler
2.1 @ControllerAdvice 注解定义全局异常处理类
@ControllerAdvice
public class GlobalExceptionHandler {
}
请确保此 GlobalExceptionHandler 类能被扫描到并装载进 Spring 容器中。
2.2 @ExceptionHandler 注解声明异常处理方法
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
String handleException(){
return "Exception Deal!";
}
}
方法 handleException() 就会处理所有 Controller 层抛出的 Exception 及其子类的异常,这是最基本的用法了。
如果 @ExceptionHandler 注解中未声明要处理的异常类型,则默认为参数列表中的异常类型。所以上面的写法,还可以写成这样:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler()
@ResponseBody
String handleException(Exception e){
return "Exception Deal! " + e.getMessage();
}
}
3.附上代码
3.1全局异常处理
此类中可以根据不同的异常做不同的处理
package com.example.exception; import com.example.entity.ResultModel; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; /** * 全局异常捕获 */ @ControllerAdvice public class GlobalDefultExceptionHandler { //声明要捕获的异常 @ExceptionHandler(value = BizException.class) @ResponseBody public ResultModel<String> defultExcepitonHandler(HttpServletRequest request, BizException e) { ResultModel<String> resultModel = new ResultModel<String>(); if(e instanceof BizException) { BizException bizException = (BizException)e; resultModel.setMessage(bizException.getMessage()); resultModel.setCode(bizException.getCode()); return resultModel; } resultModel.setCode(e.getCode()); resultModel.setMessage(e.getMessage()); return resultModel; } }
3.2自定义的异常类
package com.example.exception; /** * 异常描述 */ public class BizException extends RuntimeException{ /** * 具体异常码 */ protected int code; /** * 异常信息 */ protected String msg; public BizException(int code, String msgFormat, Object... args) { super(String.format(msgFormat, args)); this.code = code; this.msg = String.format(msgFormat, args); } public BizException(int code, String msg) { super(String.format(msg)); this.code = code; this.msg = msg; } public BizException(int code, java.lang.Exception ex) { super(ex.getMessage(), ex.getCause()); this.code = code; this.msg = ex.getMessage(); } public BizException() { super(); } public String getMsg() { return msg; } public int getCode() { return code; } /** * 实例化异常 * * @param msgFormat * @param args * @return */ public BizException newInstance(String msgFormat, Object... args) { return new BizException(this.code, msgFormat, args); } public BizException(String message, Throwable cause) { super(message, cause); } public BizException(Throwable cause) { super(cause); } public BizException(String message) { super(message); } @Override public String toString(){ return String.format("code:%s,msg:%s,RuntimeException's info:{%s}", this.code, this.msg, super.toString().equals("") ? "无" : super.toString()); } }