欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring boot错误处理机制

程序员文章站 2022-05-03 19:18:25
...

SpringBoot默认的错误处理机制
当访问一个不存在的页面,或者程序抛出异常时
默认效果:
spring boot错误处理机制
看看是不是非常丑的一个页面,和我们网站风格一点都不一样。
所以网站的错误页面都会重新写的漂亮点。
接下来学习:
如何定制错误响应页面???

  • 有模板引擎的情况下
    将错误页面命名为 错误状态码.html 放在模板引擎文件夹里的error文件夹下发生此状态码的错误就会来到这里找对应的页面spring boot错误处理机制
    比如我们在template文件夹下创建error/404.html当浏览器请求是404错误,就会使用我们自己创建的404.html页面响应,如果是其他状态码错误,还是使用默认的视图,但是如果404.html没有找到就会替换成4XX.html再查找一次。
    看看我们都可以在页面获取那些错误信息。
  • timestamp:时间戳
  • status:状态码
  • error:错误提示
  • exception:异常对象
  • message:异常消息
  • errors:JSR303数据校验的错误都在这里
    2.0以后默认是不显示exception的,需要在配置文件中开启。
server.error.include-exception=true

人家已经定义你可以获取到那些错误信息, this.errorAttributes是接口类型ErrorAttributes,实现类就一个DefaultErrorAttributes(实现了ErrorAttributes),看一下DefaultErrorAttributes的 getErrorAttributes()方法

public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = this.getErrorAttributes(webRequest, options.isIncluded(Include.STACK_TRACE));
        if (this.includeException != null) {
            options = options.including(new Include[]{Include.EXCEPTION});
        }

        if (!options.isIncluded(Include.EXCEPTION)) {
            errorAttributes.remove("exception");
        }

        if (!options.isIncluded(Include.STACK_TRACE)) {
            errorAttributes.remove("trace");
        }

        if (!options.isIncluded(Include.MESSAGE) && errorAttributes.get("message") != null) {
            errorAttributes.put("message", "");
        }

        if (!options.isIncluded(Include.BINDING_ERRORS)) {
            errorAttributes.remove("errors");
        }

        return errorAttributes;
    }

  • 没有模板引擎(模板引擎找不到这个错误页面),就会在静态资源文件夹下找;
    spring boot错误处理机制
  • 如果以上都没有找到错误页面,就是默认来到SpringBoot默认的错误提示页面;

如何定制JSON数据
第一种方法:
写了一个自定义的异常,发现前台获取不到message信息(spring boot 2.3.1),需要对配置文件进行配置。

server.error.include-message=always

此时我们在前台获取message成功。
spring boot错误处理机制
自定义一个错误信息处理的一个handler. 当触发userNotFound异常,进入该处理器,对异常信息进行处理,数据进行绑定。

package com.yangzhenxu.firstspringboot.Exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class MyExceptionHandler {

    @ResponseBody
    @ExceptionHandler(userNotFound.class)
    public Map<String,Object> handleException(Exception u){
        Map<String,Object> map=new HashMap<>();
        map.put("code","usernotfound");
        map.put("message",u.getMessage());
        return map;
    }
}

如图:此时不管是浏览器还是postman客户端发送请求都是返回json错误信息。
spring boot错误处理机制
学一个注解:
@ControllerAdvice , 这是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能:

全局异常处理
全局数据绑定
全局数据预处理
第二种方法:
捕获到异常后转发到/error,自适应响应效果。

 @ExceptionHandler(userNotFound.class)
    public String handleException(Exception e) {
        Map<String, Object> map = new HashMap(2);
        map.put("code", "500");
        map.put("msg", e.getMessage());
        return "forward:/error";
    }

spring boot错误处理机制
为甚么没有到自己的页面呢,是因为这样异常被我们捕获然后转发,显示的状态码就是200,所以在转发之前还要设置一下状态码。

  @ExceptionHandler(userNotFound.class)
    public String handleException(Exception e,HttpServletRequest request) {
        Map<String, Object> map = new HashMap(2);
        map.put("code", "500");
        map.put("msg", e.getMessage());
        request.setAttribute("javax.servlet.error.status_code", 500);
        return "forward:/error";
    }

spring boot错误处理机制
此时就来到了我们的自适应页面。
但是设置的数据就没有用了,只能使用默认的
第三种方法,将自己设置的数据也携带过去。

@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        //调用父类的方法获取默认的数据
        Map<String, Object> map = new HashMap<>(super.getErrorAttributes(webRequest, includeStackTrace));
        //从request域从获取到自定义数据
        Map<String, Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", RequestAttributes.SCOPE_REQUEST);
        map.putAll(ext);
        return map;
    }

   @ExceptionHandler(userNotFound.class)
    public String handleException(Exception e,HttpServletRequest request) {
        Map<String, Object> map = new HashMap(2);
        map.put("code", "500");
        map.put("msg", "出错了");
        request.setAttribute("ext",map);
        request.setAttribute("javax.servlet.error.status_code", 500);
        return "forward:/error";
    }
相关标签: 框架