1、控制器级别@ExceptionHandler

public class FooController{
     
    //...
    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public void handleException() {
        //
    }
}

作用:只针对@Controller起作用。

弊端:

A、每个@Controller类都要写标记@ExceptionHandler的方法,当然可以统一写Base Controller,并将其写入。但,有些@Controller继承自其他BaseController,而该BaseController在其他jar包中,无法修改。

B、不能对整个应用起作用。

2、HandlerExceptionResolver

1)、DefaultHandlerExceptionResolver

作用:将标准Spring异常解析为对应的HTTP状态码,如404,500等。参见:spring exception完整列表

弊端:没有对response的body设置内容。虽然可通过ModelAndView自行写错误内容,但不是最佳的。

2)、ResponseStatusExceptionResolver

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class MyResourceNotFoundException extends RuntimeException {
    public MyResourceNotFoundException() {
        super();
    }
    public MyResourceNotFoundException(String message, Throwable cause) {
        super(message, cause);
    }
    public MyResourceNotFoundException(String message) {
        super(message);
    }
    public MyResourceNotFoundException(Throwable cause) {
        super(cause);
    }
}

作用:使用自定义异常类,并在其上加注解@ResponseStatus,将这些异常映射到HTTP状态码。

弊端:与DefaultHandlerExceptionResolver一样,却是将状态码映射到response上,但body仍为null。

3)、自定义HandlerExceptionResolver

例子:如果客户端要求输入application / json,则在出现错误情况时,我们要确保我们返回一个以application / json编码的响应正文

@Component
public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {
 
    @Override
    protected ModelAndView doResolveException(
      HttpServletRequest request,
      HttpServletResponse response,
      Object handler,
      Exception ex) {
        try {
            if (ex instanceof IllegalArgumentException) {
                return handleIllegalArgument(
                  (IllegalArgumentException) ex, response, handler);
            }
            ...
        } catch (Exception handlerException) {
            logger.warn("Handling of [" + ex.getClass().getName() + "]
              resulted in Exception", handlerException);
        }
        return null;
    }
 
    private ModelAndView
      handleIllegalArgument(IllegalArgumentException ex, HttpServletResponse response)
      throws IOException {
        response.sendError(HttpServletResponse.SC_CONFLICT);
        String accept = request.getHeader(HttpHeaders.ACCEPT);
        ...
        return new ModelAndView();
    }
}

作用:自定义异常

弊端:返回的依旧是ModelAndView,在这里为response body设置内容。

3、@ControllerAdvice

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
 
    @ExceptionHandler(value = { IllegalArgumentException.class, IllegalStateException.class })
    protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

作用:@ControllerAdvice为支持全局的@ExceptionHandler,该机制有别于旧的MVC模型,利用ResponseEntity和@@ExceptionHandler带来了便利。

A、能够设置response的body和状态码。

B、能将多个异常映射到同一方法,以便一起处理。

C、充分利用了RESTful ResponseEntity来响应。

4、ResponseStatusException(适用于spring5及以上)

@GetMapping(value = "/{id}")
public Foo findById(@PathVariable("id") Long id, HttpServletResponse response) {
    try {
        Foo resourceById = RestPreconditions.checkFound(service.findOne(id));
 
        eventPublisher.publishEvent(new SingleResourceRetrievedEvent(this, response));
        return resourceById;
     }
    catch (MyResourceNotFoundException exc) {
         throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Foo Not Found", exc);
    }
}

作用:

A、一种类型(ResponseStatusException),多种状态码。与@ExceptionHandler相比,减少了耦合。

B、我们将不用创建那么多自定义异常类。

C、由于可通过编程方式创建异常,因此可以更好的控制异常处理。

弊端:

A、没有统一、全局的异常处理方式:对比应用程序范围的全局异常(@ControllerAdvice)来说,提供全局异常很难。

B、代码复制:在多个Controller类中复制代码。

那如何解决以上问题呢?

全局异常:@ControllerAdvice
局部异常:ResponseStatusException

但是,如果发生了相同的异常时,是重复执行还是报错?

spring boot rest api exception解决方案的更多相关文章

  1. MyBatis 强大之处 多环境 多数据源 ResultMap 的设计思想是 缓存算法 跨数据库 spring boot rest api mybaits limit 传参

    总结: 1.mybaits配置工2方面: i行为配置,如数据源的实现是否利用池pool的概念(POOLED – This implementation of DataSource pools JDBC ...

  2. 使用 JSONDoc 记录 Spring Boot RESTful API

    这个博文可以分为两部分:第一部分我将编写一个Spring Boot RESTful API,第二部分将介绍如何使用JSONDoc来记录创建的API.做这两个部分最多需要15分钟,因为使用Spring ...

  3. Spring Boot REST API 自动化测试

    Spring Boot需要写大量的Junit代码来测试REST API, 这点让不了解代码的人很头疼.如果使用REST client工具测试REST API,很多REST Client工具是不支持自动 ...

  4. Spring Boot & Restful API 构建实战!

    作者:liuxiaopeng https://www.cnblogs.com/paddix/p/8215245.html 在现在的开发流程中,为了最大程度实现前后端的分离,通常后端接口只提供数据接口, ...

  5. Spring Boot : Whitelabel Error Page解决方案

    楼主最近爱上了一个新框架--Spring Boot, 搭建快还不用写一堆xml,最重要的是自带Tomcat 真是好 pom.xml <?xml version="1.0" e ...

  6. Spring Boot 中文乱码问题解决方案汇总

    使用 Spring Boot 开发,对外开发接口供调用,传入参数中有中文,出现中文乱码,查了好多资料,总结解决方法如下: 第一步,约定传参编码格式 不管是使用httpclient,还是okhttp,都 ...

  7. Spring boot cassandra - nested exception is com.datastax.driver.core.exceptions.NoHostAvailableException

    1.在Pom.xml添加spring-boot-starter-data-cassandra依赖: <dependency> <groupId>org.springframew ...

  8. Spring Boot - Restful API

    基本用法 @GetMapping与@PostMapping不指定参数时就是指直接使用到controller一级的url就行 @GetMapping与@PathVariable对应,前者{}中的字符串和 ...

  9. 【从0到1,搭建Spring Boot+RESTful API+Shiro+Mybatis+SQLServer权限系统】06、Mybatis+SQLServer集成

    1.增加POM依赖 注意pagehelper插件,我重写过,可以到我的这篇文章了解https://www.cnblogs.com/LiveYourLife/p/9176934.html <dep ...

随机推荐

  1. C++11常用特性介绍——nullptr关键字及用法

    一.nullptr关键字及用法 1)NULL的二义性 void func(int) {} void func(int*) {} 当函数调用func(NULL)时会执行哪个函数呢? 先看C++对NULL ...

  2. SpringBoot之日志记录-专题四

    SpringBoot之日志记录-专题四 六.日志管理 6.1使用log4j记录日志 6.1.2新建log4j配置文件 文件名称log4j.properties #log4j.rootLogger=CO ...

  3. linux 基本命令学习总结

    1. linux的目录结构  (linux核心:一切皆文件) 目录结构解释 (主要的有 /etc  /home  /mnt  /opt  /usr   /tmp) 相对路径和绝对路径的区别 绝对路径  ...

  4. js加密(九)hr.bibibi md5

    1. 寻找加密js: 2. 结果: 3. execjs调用js即可.

  5. Python - ORM(数据库相关)

    1. 概念 目标:类/对象操作 -> SQL语句 -> DB API -> 再在数据库中执行.ORM做前两部,因为ORM本身无法操作数据库.参考:https://baike.baid ...

  6. leetcode菜鸡斗智斗勇系列(5)--- 寻找拥有偶数数位的数字

    1.原题: https://leetcode.com/problems/find-numbers-with-even-number-of-digits/ Given an array nums of ...

  7. 【快学springboot】5.全局异常捕获,异常流处理业务逻辑

    前言 上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的.参数异常springboot默认的返回结构: { "timestamp": ...

  8. keep-alive 用法 及activated,deactivated这两个生命周期函数

    keep-aliveProps: include - 字符串或正则表达式.只有名称匹配的组件会被缓存.exclude - 字符串或正则表达式.任何名称匹配的组件都不会被缓存.max - 数字.最多可以 ...

  9. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 按钮:按钮被点击

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. python deepcopy的替代方案

    from copy import deepcopy import marshal import timeit from multidict import CIMultiDict def test_de ...