springboot异常处理

参考文档-springboot.doc

主要内容

  • springboot默认的异常处理机制
  • 使用自定义的页面来代替默认的异常页面
  • 使用@controlleradvice+@handlerException来处理全局controller中的异常
  • 使用实现ErrorController 来处理全局异常
springboot默认的异常处理机制

由官方文档所知,默认情况下,Spring Boot提供了一个/error以合理方式处理所有错误的映射(详情参考),对于计算机客户端,它会生成一个JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个“whitelabel”错误视图,它以HTML格式呈现相同的数据

@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {
    private final ErrorProperties errorProperties;

    public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
        this(errorAttributes, errorProperties, Collections.emptyList());
    }

    public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List errorViewResolvers) {
        super(errorAttributes, errorViewResolvers);
        Assert.notNull(errorProperties, "ErrorProperties must not be null");
        this.errorProperties = errorProperties;
    }

    public String getErrorPath() {
        return this.errorProperties.getPath();
    }
//这是返回页面的
    @RequestMapping(
        produces = {"text/html"}
    )
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = this.getStatus(request);
        Map model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
        return modelAndView == null ? new ModelAndView("error", model) : modelAndView;
    }
//这是返回json格式的。
    @RequestMapping
    @ResponseBody
    public ResponseEntity> error(HttpServletRequest request) {
        Map body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = this.getStatus(request);
        return new ResponseEntity(body, status);
    }

    protected boolean isIncludeStackTrace(HttpServletRequest request, MediaType produces) {
        IncludeStacktrace include = this.getErrorProperties().getIncludeStacktrace();
        if (include == IncludeStacktrace.ALWAYS) {
            return true;
        } else {
            return include == IncludeStacktrace.ON_TRACE_PARAM ? this.getTraceParameter(request) : false;
        }
    }

    protected ErrorProperties getErrorProperties() {
        return this.errorProperties;
    }
}

在配置文件中,根据提示,可知映射路径确实是/error
image.png

测试:

    @RequestMapping("exceptiontest")
    @ResponseBody
    public Object exceptionTest(){
        throw new MyException(MyExceptionEnum.NOT_FOUND);
    }
  • 使用浏览器调用


    image.png
  • 使用postman调用


    image.png
  • 也可以直接调用/error接口,看看返回的是什么
使用自定义的页面来代替默认的异常页面

既然已经知道,springboot默认处理异常返回的是error页面,那么我们可以在templates目录下创建一个自定义的error页面




    
    Title


this is my error page


测试:此时再用浏览器调用的话,就会出现自定义的error页面


image.png
使用实现ErrorController 来处理全局异常

我们可以模仿BasicErrorController来自定义一个ErrorController来处理全局的异常

@Controller
@RequestMapping("/error")
public class MyErrorController implements ErrorController {
    private ErrorProperties errorProperties;
    @Override
    public String getErrorPath() {
        return this.errorProperties.getPath();
    }

    @RequestMapping(produces = "text/html")
    public ModelAndView errorHtml(HttpServletRequest request,
                                  HttpServletResponse response) {
        HashMap map = new HashMap<>();
        map.put("error","error_message");
        ModelAndView modelAndView = new ModelAndView("error",map);
        return modelAndView;
    }

    @RequestMapping
    @ResponseBody
    public ResponseEntity> error(HttpServletRequest request) {
        HashMap map = new HashMap<>();
        map.put("error","error_message");
        return new ResponseEntity>(map,HttpStatus.NOT_FOUND);
    }
}

error.html




    Getting Started: Serving Web Content
    


    

结果:
image.png

那么为什么springboot会使用我们自定义的ErrorController而不使用自定义的了呢?可以在ErrorMvcAutoConfiguration类中发现,要是有了ErrorController,那么BasicErrorController就不会被注入到spring容器中

    @Bean
    @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
    public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
        return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
                this.errorViewResolvers);
    }
使用@controlleradvice+@handlerException来处理全局controller中的异常

1.定义一个自定义的异常枚举类

@Getter
@AllArgsConstructor
public enum  MyExceptionEnum {
                NOT_FOUND("404","不存在"),
                NOT_ALLOWED("401","权限不够");
    private String code;
    private String message;
}

2.自定义异常类

@Data
@AllArgsConstructor
public class MyException extends   RuntimeException {
    private MyExceptionEnum myExceptionEnum;
}

3.定义一个异常处理类

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler()
    @ResponseBody
    public ResponseEntity handlerControllerException(Exception ex){
        if(ex instanceof MyException){
            MyExceptionEnum myExceptionEnum = ((MyException) ex).getMyExceptionEnum();
            return new ResponseEntity(new ResponseMap(myExceptionEnum.getCode(),myExceptionEnum.getMessage()), HttpStatus.NOT_FOUND);
        }
        return  null;
    }
}

测试:
image.png

你可能感兴趣的:(springboot异常处理)