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. vue-element-admin 引入高德地图并做海量点标记

    第一步: 首先在index.html入口文件中添加引入高德地图的js,并填写自己在官网申请的key.如果没有申请不填写也是可以的. plugin:项目中如果有需要引入插件则使用没有直接去掉就行. &l ...

  2. 使用package.json安装模块

    node.js模块的安装可以使用npm安装,如下: $ npm install <Module Name> 每个项目的根目录下面,一般都需要一个package.json文件,定义了这个项目 ...

  3. SignalR Connection has not been fully initialized

    在使用 SignalR 过程中遇到 SignalR: Connection has not been fully initialized. Use .start().done() or .start( ...

  4. Centos7 安装redis及简单使用

    一.redis的介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset( ...

  5. Java连载80-数字类格式、随机数、BigDecimal

    一.数字类 1.关于数字格式化:java.text.DecimalFormat; 2.数字格式元素: # 任意数字 , 千分位 . 小数点 0 不够补零 package com.bjpowernode ...

  6. python表白代码1.0桃心输出

    python爱心表达函数初级版本:def my_heart(a,b=2): print("\n".join(["".join([(a[(x-y) % len(a ...

  7. C# 中[DllImport("user32.dll")]和extern用法和示例----转载

    原文:https://blog.csdn.net/michellehsiao/article/details/7629746         extern 修饰符用于声明在外部实现的方法.extern ...

  8. 【剑指Offer面试编程题】题目1352:和为S的两个数字--九度OJ

    题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k, ...

  9. HDU 5525:Product 欧拉定理

    Product  Accepts: 21  Submissions: 171  Time Limit: 6000/3000 MS (Java/Others)  Memory Limit: 131072 ...

  10. webpack配置自动打包重新运行npm run dev出现报错

    webpack配置自动打包重新运行npm run dev出现报错 运行npm run dev出现如下报错 Listening at http://localhost:8080(node:2328) U ...