Spring ResponseStatusException – 响应状态异常(Spring ResponseStatusException

最后修改: 2018年 2月 19日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll discuss the new ResponseStatusException class introduced in Spring 5. This class supports the application of HTTP status codes to HTTP responses.

在这个快速教程中,我们将讨论Spring 5中新引入的ResponseStatusException 类。这个类支持将HTTP状态码应用于HTTP响应。

A RESTful application can communicate the success or failure of an HTTP request by returning the right status code in the response to the client. Simply put, an appropriate status code can help the client to identify problems that might have occurred while the application was dealing with the request.

一个RESTful应用程序可以通过在响应中向客户端返回正确的状态代码来传达HTTP请求的成功或失败。简单地说,适当的状态代码可以帮助客户端识别应用程序在处理请求时可能出现的问题。

2. ResponseStatus

2.响应状态

Before we delve into ResponseStatusException, let’s quickly take a look at the @ResponseStatus annotation. This annotation was introduced in Spring 3 for applying HTTP Status code to an HTTP response.

在我们深入了解ResponseStatusException之前,让我们先来看看@ResponseStatus注解。这个注解是在Spring 3中引入的,用于对HTTP响应应用HTTP状态代码

We can use the @ResponseStatus annotation to set the status and reason in our HTTP response:

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

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

If this exception is thrown while processing an HTTP request, then the response will include the HTTP status specified in this annotation.

如果在处理HTTP请求时抛出这个异常,那么响应将包括这个注解中指定的HTTP状态。

One drawback of the @ResponseStatus approach is that it creates tight coupling with the exception. In our example, all exceptions of type ActorNotFoundException will generate the same error message and status code in the response.

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

3. ResponseStatusException

3.ResponseStatusException

ResponseStatusException is a programmatic alternative to @ResponseStatus and is the base class for exceptions used for applying a status code to an HTTP response. It’s a RuntimeException and hence not required to be explicitly added in a method signature.

ResponseStatusException@ResponseStatus的程序化替代,是用于对HTTP响应应用状态码的异常的基类。它是一个RuntimeException,因此不需要在方法签名中明确添加。

Spring provides 3 constructors to generate ResponseStatusException:

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, constructor arguments:

ResponseStatusException,构造器参数。

  • status – an HTTP status set to the HTTP response
  • reason – a message explaining the exception set to the HTTP response
  • cause – a Throwable cause of the ResponseStatusException

Note: in Spring, HandlerExceptionResolver intercepts and processes any exception raised and not handled by a Controller.

注意:在Spring中,HandlerExceptionResolver拦截和处理任何引发的、未被控制器处理的异常。

One of these handlers, ResponseStatusExceptionResolver, looks for any ResponseStatusException or uncaught exceptions annotated by @ResponseStatus and then extracts the HTTP Status code & reason and includes them in the HTTP response.

其中一个处理程序,ResponseStatusExceptionResolver,寻找任何ResponseStatusException或由@ResponseStatus注释的未捕获的异常,然后提取HTTP状态代码和原因,并将其纳入HTTP响应。

3.1. ResponseStatusException Benefits

3.1.ResponseStatusException好处

ResponseStatusException usage has few benefits:

ResponseStatusException的使用没有什么好处。

  • Firstly, exceptions of the same type can be processed separately and different status codes can be set on the response, reducing tight coupling
  • Secondly, it avoids the creation of unnecessary additional exception classes
  • Finally, it provides more control over exception handling, as the exceptions can be created programmatically

4. Examples

4.实例

4.1. Generate ResponseStatusException

4.1.产生ResponseStatusException

Now, let’s see an example that generates a ResponseStatusException :

现在,让我们看看一个产生ResponseStatusException的例子。

@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);
    }
}

Spring Boot provides a default /error mapping, returning a JSON response with HTTP status.

Spring Boot提供了一个默认的/error映射,返回一个带有HTTP状态的JSON响应。

Here’s how the response looks:

以下是反应的情况。

$ curl -i -s -X GET http://localhost:8081/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 26 Dec 2020 19:38:09 GMT

{
    "timestamp": "2020-12-26T19:38:09.426+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "",
    "path": "/actor/8"
}

Starting from the 2.3 version, Spring Boot doesn’t include an error message on the default error page. The reason is to reduce the risk of leaking information to a client

从2.3版本开始,Spring Boot在默认错误页面上不包含错误信息。原因是为了减少向客户泄露信息的风险


To change the default behavior, we can use a server.error.include-message property.

要改变默认行为,我们可以使用server.error.include-message属性。

Let’s set it to always and see what happens:

让我们把它设置为always,看看会发生什么。

$ curl -i -s -X GET http://localhost:8081/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 26 Dec 2020 19:39:11 GMT

{
    "timestamp": "2020-12-26T19:39:11.426+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "Actor Not Found",
    "path": "/actor/8"
}

As we can see, this time, the response contains an “Actor Not Found” error message.

我们可以看到,这一次,响应包含一个“Actor Not Found”错误信息。

4.2. Different Status Code – Same Exception Type

4.2.不同的状态代码 – 相同的异常类型

Now, let’s see how a different status code is set to HTTP response when the same type of exception is raised:

现在,让我们来看看当同一类型的异常发生时,HTTP响应是如何设置不同状态代码的。

@PutMapping("/actor/{id}/{name}")
public String updateActorName(
  @PathVariable("id") int id, 
  @PathVariable("name") String name) {
 
    try {
        return actorService.updateActor(id, name);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.BAD_REQUEST, "Provide correct Actor Id", ex);
    }
}

Here’s how the response looks:

以下是反应的情况。

$ curl -i -s -X PUT http://localhost:8081/actor/8/BradPitt
HTTP/1.1 400
...
{
    "timestamp": "2018-02-01T04:28:32.917+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Provide correct Actor Id",
    "path": "/actor/8/BradPitt"
}

5. Conclusion

5.总结

In this quick tutorial, we discussed how to construct a ResponseStatusException in our program.

在这个快速教程中,我们讨论了如何在我们的程序中构建一个ResponseStatusException

We also emphasized how it’s programmatically a better way to set HTTP status codes in HTTP Response than @ResponseStatus annotation.

我们还强调了在HTTP响应中设置HTTP状态码,在程序上是比@ResponseStatus注释更好的方式。

As always, the full source code is available over on GitHub.

一如既往,完整的源代码可在GitHub上获得