前言 : spring boot 默认支持自适应的全局错误异常处理。当浏览器访问返回错误页面,当移动设备或者支持异步请求返回对应的json格式。

 

一、spring Boot 自适应错误处理

如果你想拥有springboot 默认自适应错误处理 ,将错误异常交给默认的控制器 /error 。

tips: 浏览器能显示错误异常页面, 是根据不同的错误响应码给浏览器。

  1. 定义错误处理器
@ControllerAdvice
public class ExceptionsHandler {
    

     @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public String httpRequestMethodNotSupportedException(Exception e, HttpServletRequest request) {
        e.printStackTrace();
        String method = ((HttpRequestMethodNotSupportedException) e).getMethod();
        return setFailMessage(request, method.concat("请求方式不正确"));
    }


    @ExceptionHandler({Exception.class})
    public String exceptionHandler(Exception e, HttpServletRequest request) {
        e.printStackTrace();
        return setFailMessage(request, "服务器开小差了");
    }

    // 根据自己业务需要配置不同的错误异常...... 

    // 将错误异常交给springboot管理
    private String setFailMessage(HttpServletRequest request, String msg) {

        request.setAttribute("javax.servlet.error.message", msg);
        return "forward:/error";
    }
}

    2. 修改默认的错误属性

@Component
public class ExceptionConfig extends DefaultErrorAttributes {


    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        // 从请求中拿到请求状态码和异常消息。这里的状态码由spring设置进去的。
        Integer statusCode = (Integer) webRequest.getAttribute("javax.servlet.error.status_code", 0);
        String msg = (String)webRequest.getAttribute("javax.servlet.error.message", 0);
        // 构建自定义错误信息返回
        return BeanUtil.beanToMap(JSONReturn.buildFailure(StringUtils.isEmpty(msg)?getStatusMessage(statusCode) : msg, statusCode));
    }


    // 获取不到错误信息,说明这些异常是spring 抛出来的。可以直接根据不同的状态码去获取不同的错误提示。也可以根据自己的业务需求更改提示信息。
    private String getStatusMessage(Integer statusCode) {
        String defaultMessage = "服务器异常";
        if(ObjectUtil.isNull(statusCode))  return defaultMessage ;

        for (HttpStatus httpStatus : HttpStatus.values()) {
            if (statusCode == httpStatus.value()) return httpStatus.getReasonPhrase();
        }
        return defaultMessage;
    }
}

3 .修改自定义的错误页面

1. 如果你使用了模版引擎,resources/templates 下创建error目录。如果没有resources/static 下创建error目录

2. 将你的错误页面放在里面,如:404.html, 500.html  ,如果401 ,403,404等错误页面你想使用同一个页面 你可以取名为4xx.html, 按照状态码精确优先匹配规则找到页面展示。 

注意: 以上都是springboot默认去寻找的错误页面。名字不能随便改。 

浏览器效果: 

spring boot date 全局格式化 spring boot全局异常_服务器

Postman效果:  

spring boot date 全局格式化 spring boot全局异常_错误异常_02

 

二、前后分离的应用

前后分离项目,只需提供json数据就可以了。

方式一:

1. 定义全局的错误异常

@ControllerAdvice
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public class ExceptionsHandler {

    // 配置了throw-exception-if-no-handler-found: true 才会触发这个异常
    @ExceptionHandler(NoHandlerFoundException.class)
    public JSONReturn handlerNoFoundException(Exception e) {
        e.printStackTrace();
        return JSONReturn.buildFailure("路径不存在,请检查路径是否正确",HttpStatus.NOT_FOUND.value());
    }

 @ExceptionHandler({Exception.class})
    public JSONReturn exceptionHandler(Exception e) {
        e.printStackTrace();
        return JSONReturn.buildFailure("服务器异常");
    }
}

2 .配置yaml

spring:
  # 抛出所有异常信息
  mvc:
    throw-exception-if-no-handler-found: true
  # 2.4.0 版后过时,替换配置为:  spring.web.resources.add-mappings=false
  resources:
    add-mappings: false

这种方式会禁用映射。会导致一些静态资源访问不到。[如果你的项目里没有静态资源,可以这样配置,否者这样配置了后,访问不到静态资源]

解决办法:  在web配置文件中,重写 `addResourceHandlers()` 方法,

贴出源码:

spring boot date 全局格式化 spring boot全局异常_错误异常_03

方式二: 

思路: 修改默认异常处理器

1.  定义全局的错误异常

@ControllerAdvice
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public class ExceptionsHandler {


 @ExceptionHandler({Exception.class})
    public JSONReturn exceptionHandler(Exception e) {
        e.printStackTrace();
        return JSONReturn.buildFailure("服务器异常");
    }
}

2. 重新springboot默认提供错误处理器

@Controller
public class NotFoundException implements ErrorController {
 
    @Override
    public String getErrorPath() {
        return "/error";
    }
 
    // 当404错误被/error拦截
    @RequestMapping(value = {"/error"})
    @ResponseBody
    public Object error(HttpServletRequest request) {
        Integer state = (Integer)request.getAttribute("javax.servlet.error.status_code");
        return JSONReturn.buildFailure(getStatusMessage(state), state);
    }

    private String getStatusMessage(Integer statusCode) {
        String defaultMessage = "服务器异常";
        if(ObjectUtil.isNull(statusCode))  return defaultMessage ;

        for (HttpStatus httpStatus : HttpStatus.values()) {
            if (statusCode == httpStatus.value()) return httpStatus.getReasonPhrase();
        }
        return defaultMessage;
    }
}

 

spring boot date 全局格式化 spring boot全局异常_错误异常_04