我项目中的所有控制器都从一个使用@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,构造函数参数:
注意:在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有什么好处?
那权衡呢?
我们还应注意,可以在一个应用程序中结合使用不同的方法。
例如,我们可以全局实现@ControllerAdvice,也可以局部实现ResponseStatusExceptions。但是,我们需要注意:如果可以以多种方式处理相同的异常,我们可能会注意到一些令人惊讶的行为。一种可能的约定是始终以一种方式处理一种特定类型的异常。