ResponseStatusException

ResponseStatusException

我项目中的所有控制器都从一个使用@ExceptionHandler批注的基本控制器扩展而来。看起来我当前正在使用的东西比春天引入的处理异常的新方法要老一些,我试图通过用最新的ExceptionHandler类替换ResponseStatusException批注来更新我的项目。

关于如何正确执行操作的任何提示?

最佳答案

在深入研究ResponseStatusException之前,让我们快速看一下 @ResponseStatus 批注。该注释是在Spring 3中引入的,用于将HTTP状态代码应用于HTTP响应。

我们可以使用@ResponseStatus批注来设置HTTP响应中的状态和原因:

@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found")
public class ActorNotFoundException extends Exception {
    // ...
}

如果在处理HTTP请求时抛出此异常,则响应将包括此批注中指定的HTTP状态。

@ResponseStatus方法的一个缺点是,它与异常会产生紧密耦合。在我们的示例中,所有类型为ActorNotFoundException的异常都会在响应中生成相同的错误消息和状态代码。

ResponseStatusException

ResponseStatusException是@ResponseStatus的编程替代方案,并且是用于将状态代码应用于HTTP响应的异常的基类。这是RuntimeException,因此不需要在方法签名中明确添加。

Spring提供了3个构造函数来生成ResponseStatusException:
ResponseStatusException(HttpStatus status)
ResponseStatusException(HttpStatus status, java.lang.String reason)
ResponseStatusException(
  HttpStatus status,
  java.lang.String reason,
  java.lang.Throwable cause
)

ResponseStatusException,构造函数参数:
  • status – HTTP状态设置为HTTP响应
  • 原因–一条消息,解释设置为HTTP响应的异常
  • 原因– ResponseStatusException的可抛出原因

  • 注意:在Spring中,HandlerExceptionResolver拦截并处理任何引发的但未由Controller处理的异常。

    这些处理程序之一,ResponseStatusExceptionResolver,查找@ResponseStatus注释的任何ResponseStatusException或未捕获的异常,然后提取HTTP状态代码和原因,并将其包括在HTTP响应中。

    ResponseStatusException好处

    使用ResponseStatusException有几个好处:
  • 首先,可以分别处理相同类型的异常,并且可以在响应中设置不同的状态代码,从而减少紧密耦合
  • 其次,它避免了创建不必要的其他异常类
  • 最后,它提供了对异常处理的更多控制,因为可以以编程方式创建异常

  • Spring 5引入了ResponseStatusException类。我们可以创建一个实例,提供HttpStatus以及可选的原因和原因:
    @GetMapping("/actor/{id}")
    public String getActorName(@PathVariable("id") int id) {
        try {
            return actorService.getActor(id);
        } catch (ActorNotFoundException ex) {
            throw new ResponseStatusException(
            HttpStatus.NOT_FOUND, "Actor Not Found", ex);
        }
    }
    

    使用ResponseStatusException有什么好处?
  • 出色的原型制作:我们可以快速实现基本解决方案
  • 一种类型,多种状态代码:一种异常类型可以导致多种不同的响应。与@ExceptionHandler
  • 相比,这减少了紧密耦合
  • 我们将不必创建许多自定义异常类
  • 由于可以以编程方式创建异常,因此可以更好地控制异常处理

    那权衡呢?
  • 没有统一的异常处理方式:强制执行一些应用程序范围的约定,而不是@ControllerAdvice,后者提供了全局方法
  • 代码复制:我们可能会发现自己在多个控制器中复制代码

  • 我们还应注意,可以在一个应用程序中结合使用不同的方法。

    例如,我们可以全局实现@ControllerAdvice,也可以局部实现ResponseStatusExceptions。但是,我们需要注意:如果可以以多种方式处理相同的异常,我们可能会注意到一些令人惊讶的行为。一种可能的约定是始终以一种方式处理一种特定类型的异常。

    09-27 12:03