SpringResponseStatusException

编程

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.

2. ResponseStatus

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.

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

1

2

3

4

@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.

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.

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.

Spring provides 3 constructors to generate ResponseStatusException:

1

2

3

4

5

6

7

ResponseStatusException(HttpStatus status)

ResponseStatusException(HttpStatus status, java.lang.String reason)

ResponseStatusException(

  

HttpStatus status,

  

java.lang.String reason,

  

java.lang.Throwable cause

)

ResponseStatusException, constructor arguments:

  • status – an HTTP status set to HTTP response
  • reason – a message explaining the exception set to 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.

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.

3.1. ResponseStatusException Benefits

ResponseStatusException usage has few benefits:

  • 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 creation of unnecessary additional exception classes
  • Finally, it provides more control over exception handling, as the exceptions can be created programmatically

4. Examples

4.1. Generate ResponseStatusException

Now, let"s us see an example which generates a ResponseStatusException :

1

2

3

4

5

6

7

8

9

@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 and the exception message.

Here’s how the response looks:

1

2

3

4

5

6

7

8

9

10

11

12

13

$ curl -i -s -X GET http:

//localhost:8080/actor/8

HTTP/1.1 404

Content-Type: application/json;charset=UTF-8

Transfer-Encoding: chunked

Date: Sun, 28 Jan 2018 19:48:10 GMT

 

{

    

"timestamp"

:

"2018-01-28T19:48:10.471+0000"

,

    

"status"

: 404,

    

"error"

:

"Not Found"

,

    

"message"

:

"Actor Not Found"

,

    

"path"

:

"/actor/8"

}

4.2. Different Status Code – Same Exception Type

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

1

2

3

4

5

6

7

8

9

10

11

12

@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:

1

2

3

4

5

6

7

8

9

10

$ curl -i -s -X PUT http:

//localhost:8080/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

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

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

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

以上是 SpringResponseStatusException 的全部内容, 来源链接: utcz.com/z/513017.html

回到顶部