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. Python学习第十七课——组合

    组合1 #组合 1 class Hand: pass class Foot: pass class Trunk: pass class Head: pass class Person: def __i ...

  2. Linux命令:ip命令

    ip命令功能:配置网络属性 一.ip link 系列 ip link ip [-s] link show        # 查看默认信息 ip link show eth0 ip link show ...

  3. task20160125

    http://task.zbj.com/2034844/n15o1.html 百度开放平台--首页>帮助文档首页>Frontia>Android开发指南>个人数据存储 http ...

  4. 嵌入式编程中使用 do{...} while(0) 的解释

    最近在看esp32的idf,有一些宏定义使用了do while(0)这种看起来好像没啥用的代码.然后我查了一下资料,发现在linux内核代码中经常用到这个东西! 现在就将这个东西整理一下. 为什么在内 ...

  5. 巧用DOS命令合并多个文本文件的内容

    假设,在网上下载了一本小说.这本小说是由100多个文本文件组成的.这个时候,将这100多个文本文件的内容全部合并到一个文本文件中,阅读起来就会显得很方便     (1)首先,使用本书中“批量按序更改文 ...

  6. Java单例模式:为什么我强烈推荐你用枚举来实现单例模式

    单例模式简介 单例模式是 Java 中最简单,也是最基础,最常用的设计模式之一.在运行期间,保证某个类只创建一个实例,保证一个类仅有一个实例,并提供一个访问它的全局访问点.下面就来讲讲Java中的N种 ...

  7. Springboot 项目启动设置

    //配置默认访问路径 并且自动打开浏览器  需要创建独立文件 @Controller public class HomeController {     @RequestMapping("/ ...

  8. Laradock 使用中遇到的问题汇总

    1.ErrorException] mkdir (): Permission denied 解决:权限不够,thinkphp5下,runtime 文件夹改777,文件所有者改为 laradock(进入 ...

  9. oracle中 lob类型

    LOB大型对象(大数据字段类型) 分为:-BLOB: Binary 二进制大型对象 ,适用于存非文本型数据(程序,图像,影音) -CLOB:Character  字符型大型对象,适用于存储文本型数据( ...

  10. sklearn学习笔记(1)--make_blobs函数及相应参数简介

    make_blobs方法: sklearn.datasets.make_blobs(n_samples=100,n_features=2,centers=3, cluster_std=1.0,cent ...