@ControllerAdvice 注解定义全局异常处理类
@ControllerAdvice
public class GlobalExceptionHandler {
}
@ExceptionHandler 注解声明异常处理方法
@ControllerAdvice
public class GlobalExceptionHandler{
@ExceptionHandler(Exception
.class)
@ResponseBody
public String
handleException() {
ex
.printStackTrace();
return "fail";
}
}
方法handleException()会处理所有Controller层抛出的Exception及其子类的异常,Controller层就不需要单独处理异常了。 但如上代码只能处理 Controller 层的异常,对于未进入Controller的异常,如Interceptor(拦截器)层的异常,Spring 框架层的异常无效,还是会将错误直接返回给用户。对此,只需要在配置文件中添加:spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
被 @ExceptionHandler 注解的方法还可以声明很多种参数类型,具体可以参考文档:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html 这里我选择了httpServletRequest, HttpServletResponse httpServletResponse, Exception ex三个参数,应用如下:
@ControllerAdvice
public class GlobalExceptionHandler{
@ExceptionHandler(Exception
.class)
@ResponseBody
public CommonReturnType
handleException(HttpServletRequest httpServletRequest
, HttpServletResponse httpServletResponse
, Exception ex
) {
ex
.printStackTrace();
Map
<String,Object> responseData
= new HashMap<>();
if( ex
instanceof BusinessException){
BusinessException businessException
= (BusinessException
)ex
;
responseData
.put("errCode",businessException
.getErrCode());
responseData
.put("errMsg",businessException
.getErrMsg());
}else if(ex
instanceof ServletRequestBindingException){
responseData
.put("errCode",BusinessError
.UNKNOWN_ERROR
.getErrCode());
responseData
.put("errMsg","url绑定路由问题");
}else if(ex
instanceof NoHandlerFoundException){
responseData
.put("errCode",BusinessError
.UNKNOWN_ERROR
.getErrCode());
responseData
.put("errMsg","没有找到对应的访问路径");
}else{
responseData
.put("errCode", BusinessError
.UNKNOWN_ERROR
.getErrCode());
responseData
.put("errMsg", BusinessError
.UNKNOWN_ERROR
.getErrMsg());
}
return CommonReturnType
.create(responseData
,"fail");
}
}
如此,所有的 Controller 层的异常日志都可以通过GlobalExceptionHandler 记录。Controller 层也不需要在手动记录异常日志了。