Document i8n for RFC 7807 problem details
Expand the documentation for error responses and add details on using a MessageSource to customize and internationalize error details. See gh-28814
This commit is contained in:
@@ -3492,28 +3492,35 @@ include::webflux-cors.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
[[webflux-ann-rest-exceptions]]
|
||||
== REST API exceptions
|
||||
[.small]#<<web.adoc#mvc-ann-rest-exceptions, Web MVC>>#
|
||||
== Error Responses
|
||||
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions, Web MVC>>#
|
||||
|
||||
A common requirement for REST services is to include details in the body of an error
|
||||
response. The Spring Framework supports the "Problem Details for HTTP APIs"
|
||||
specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807]. These are the main
|
||||
abstractions for this support:
|
||||
A common requirement for REST services is to include details in the body of error
|
||||
responses. The Spring Framework supports the "Problem Details for HTTP APIs"
|
||||
specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].
|
||||
|
||||
The following are the main abstractions for this support:
|
||||
|
||||
- `ProblemDetail` -- representation for an RFC 7807 problem detail; a simple container
|
||||
for both standard fields defined in the spec, and for non-standard ones.
|
||||
- `ErrorResponse` -- contract to expose HTTP error response details including HTTP
|
||||
status, response headers, and a body in the format of RFC 7807; this allows exceptions to
|
||||
encapsulate and expose the details of how they map to an HTTP response. All Spring MVC
|
||||
encapsulate and expose the details of how they map to an HTTP response. All Spring WebFlux
|
||||
exceptions implement this.
|
||||
- `ErrorResponseException` -- basic `ErrorResponse` implementation that others
|
||||
can use as a convenient base class.
|
||||
- `ResponseEntityExceptionHandler` -- convenient base class for an
|
||||
<<webflux-ann-controller-advice,@ControllerAdvice>> that handles all Spring MVC exceptions,
|
||||
<<webflux-ann-controller-advice,@ControllerAdvice>> that handles all Spring WebFlux exceptions,
|
||||
and any `ErrorResponseException`, and renders an error response with a body.
|
||||
|
||||
You can return `ProblemDetail` or `ErrorResponse` directly from `@RequestMapping` or
|
||||
from `@ExceptionHandler` controller methods to render an RFC 7807 response as follows:
|
||||
|
||||
|
||||
[[webflux-ann-rest-exceptions-render]]
|
||||
=== Render
|
||||
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-render, Web MVC>>#
|
||||
|
||||
You can return `ProblemDetail` or `ErrorResponse` from any `@ExceptionHandler` or from
|
||||
any `@RequestMapping` method to render an RFC 7807 response as follows:
|
||||
|
||||
- The `status` property of `ProblemDetail` determines the HTTP status.
|
||||
- The `instance` property of `ProblemDetail` is set from the current URL path, if not
|
||||
@@ -3522,20 +3529,106 @@ already set.
|
||||
"application/problem+json" over "application/json" when rendering a `ProblemDetail`,
|
||||
and also falls back on it if no compatible media type is found.
|
||||
|
||||
You can extend an RFC 7807 response with non-standard fields as follows:
|
||||
To enable RFC 7807 responses for Spring WebFlux exceptions and for any
|
||||
`ErrorResponseException`, extend `ResponseEntityExceptionHandler` and declare it as an
|
||||
<<webflux-ann-controller-advice,@ControllerAdvice>> in Spring configuration. The handler
|
||||
obtains HTTP status, headers, and error details from each exception and prepares a
|
||||
`ResponseEntity`.
|
||||
|
||||
- Insert into the "properties" `Map` of `ProblemDetail`. When using the Jackson
|
||||
|
||||
|
||||
[[webflux-ann-rest-exceptions-non-standard]]
|
||||
=== Non-Standard Fields
|
||||
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-non-standard, Web MVC>>#
|
||||
|
||||
You can extend an RFC 7807 response with non-standard fields in one of two ways.
|
||||
|
||||
One, insert into the "properties" `Map` of `ProblemDetail`. When using the Jackson
|
||||
library, the Spring Framework registers `ProblemDetailJacksonMixin` that ensures this
|
||||
"properties" `Map` is unwrapped and rendered as top level JSON properties in the
|
||||
response, and likewise any unknown property during deserialization is inserted into
|
||||
this `Map`.
|
||||
- Extend `ProblemDetail` to add dedicated non-standard properties. The copy constructor
|
||||
in `ProblemDetail` allows a sub-class to make it easy to be created from an existing
|
||||
`ProblemDetail`. This could be done centrally, e.g. from an `@ControllerAdvice` such as
|
||||
`ResponseEntityExceptionHandler` that re-creates the `ProblemDetail` of an exception into
|
||||
a subclass with the additional non-standard fields.
|
||||
|
||||
A client application can catch `WebClientResponseException` and use its
|
||||
You can also extend `ProblemDetail` to add dedicated non-standard properties.
|
||||
The copy constructor in `ProblemDetail` allows a sub-class to make it easy to be created
|
||||
from an existing `ProblemDetail`. This could be done centrally, e.g. from an
|
||||
`@ControllerAdvice` such as `ResponseEntityExceptionHandler` that re-creates the
|
||||
`ProblemDetail` of an exception into a subclass with the additional non-standard fields.
|
||||
|
||||
|
||||
|
||||
[[webflux-ann-rest-exceptions-i8n]]
|
||||
=== Internationalization
|
||||
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-i8n, Web MVC>>#
|
||||
|
||||
It is a common requirement to internationalize error response details, and good practice
|
||||
to customize the problem details for Spring WebFlux exceptions. This is supported as follows:
|
||||
|
||||
- Each `ErrorResponse` exposes a message code and message code arguments to resolve the
|
||||
problem "detail" field through a <<core.adoc#context-functionality-messagesource,MessageSource>>.
|
||||
The actual message code value is parameterized with placeholders, e.g.
|
||||
`"HTTP method {0} not supported"` to be expanded from the arguments.
|
||||
- `ResponseEntityExceptionHandler` uses the message code and the message arguments
|
||||
to resolve the problem "detail" field.
|
||||
|
||||
Message codes default to "problemDetail." + the fully qualified exception class name. Some
|
||||
exceptions may expose additional message codes in which case a suffix is added to
|
||||
the default message code. The table below lists message arguments and codes for Spring
|
||||
WebFlux exceptions:
|
||||
|
||||
[[webflux-ann-rest-exceptions-codes]]
|
||||
[cols="1,1,2", options="header"]
|
||||
|===
|
||||
| Exception | Message Code | Message Code Arguments
|
||||
|
||||
| `UnsupportedMediaTypeStatusException`
|
||||
| (default)
|
||||
| `{0}` the media type that is not supported, `{1}` list of supported media types
|
||||
|
||||
| `UnsupportedMediaTypeStatusException`
|
||||
| (default) + ".parseError"
|
||||
|
|
||||
|
||||
| `MissingRequestValueException`
|
||||
| (default)
|
||||
| `{0}` a label for the value (e.g. "request header", "cookie value", ...), `{1}` the value name
|
||||
|
||||
| `UnsatisfiedRequestParameterException`
|
||||
| (default)
|
||||
| `{0}` the list of parameter conditions
|
||||
|
||||
| `WebExchangeBindException`
|
||||
| (default)
|
||||
| `{0}` the list of global errors, `{1}` the list of field errors.
|
||||
Message codes and arguments for each error within the `BindingResult` are also resolved
|
||||
via `MessageSource`.
|
||||
|
||||
| `NotAcceptableStatusException`
|
||||
| (default)
|
||||
| `{0}` list of supported media types
|
||||
|
||||
| `NotAcceptableStatusException`
|
||||
| (default) + ".parseError"
|
||||
|
|
||||
|
||||
| `ServerErrorException`
|
||||
| (default)
|
||||
| `{0}` the failure reason provided to the class constructor
|
||||
|
||||
| `MethodNotAllowedException`
|
||||
| (default)
|
||||
| `{0}` the current HTTP method, `{1}` the list of supported HTTP methods
|
||||
|
||||
|===
|
||||
|
||||
|
||||
|
||||
[[webflux-ann-rest-exceptions-client]]
|
||||
=== Client Handling
|
||||
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-client, Web MVC>>#
|
||||
|
||||
A client application can catch `WebClientResponseException`, when using the `WebClient`,
|
||||
or `RestClientResponseException` when using the `RestTemplate`, and use their
|
||||
`getResponseBodyAs` methods to decode the error response body to any target type such as
|
||||
`ProblemDetail`, or a subclass of `ProblemDetail`.
|
||||
|
||||
|
||||
@@ -4824,13 +4824,14 @@ include::webmvc-cors.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
[[mvc-ann-rest-exceptions]]
|
||||
== REST API exceptions
|
||||
== Error Responses
|
||||
[.small]#<<web-reactive.adoc#webflux-ann-rest-exceptions, WebFlux>>#
|
||||
|
||||
A common requirement for REST services is to include details in the body of an error
|
||||
response. The Spring Framework supports the "Problem Details for HTTP APIs"
|
||||
specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807]. These are the main
|
||||
abstractions for this support:
|
||||
A common requirement for REST services is to include details in the body of error
|
||||
responses. The Spring Framework supports the "Problem Details for HTTP APIs"
|
||||
specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807].
|
||||
|
||||
The following are the main abstractions for this support:
|
||||
|
||||
- `ProblemDetail` -- representation for an RFC 7807 problem detail; a simple container
|
||||
for both standard fields defined in the spec, and for non-standard ones.
|
||||
@@ -4844,8 +4845,14 @@ can use as a convenient base class.
|
||||
<<mvc-ann-controller-advice,@ControllerAdvice>> that handles all Spring MVC exceptions,
|
||||
and any `ErrorResponseException`, and renders an error response with a body.
|
||||
|
||||
You can return `ProblemDetail` or `ErrorResponse` directly from `@RequestMapping` or
|
||||
from `@ExceptionHandler` controller methods to render an RFC 7807 response as follows:
|
||||
|
||||
|
||||
[[mvc-ann-rest-exceptions-render]]
|
||||
=== Render
|
||||
[.small]#<<web-reactive.adoc#webflux-ann-rest-exceptions-render, WebFlux>>#
|
||||
|
||||
You can return `ProblemDetail` or `ErrorResponse` from any `@ExceptionHandler` or from
|
||||
any `@RequestMapping` method to render an RFC 7807 response as follows:
|
||||
|
||||
- The `status` property of `ProblemDetail` determines the HTTP status.
|
||||
- The `instance` property of `ProblemDetail` is set from the current URL path, if not
|
||||
@@ -4854,18 +4861,127 @@ already set.
|
||||
"application/problem+json" over "application/json" when rendering a `ProblemDetail`,
|
||||
and also falls back on it if no compatible media type is found.
|
||||
|
||||
You can extend an RFC 7807 response with non-standard fields as follows:
|
||||
To enable RFC 7807 responses for Spring MVC exceptions and for any
|
||||
`ErrorResponseException`, extend `ResponseEntityExceptionHandler` and declare it as an
|
||||
<<mvc-ann-controller-advice,@ControllerAdvice>> in Spring configuration. The handler
|
||||
obtains HTTP status, headers, and error details from each exception and prepares a
|
||||
`ResponseEntity`.
|
||||
|
||||
- Insert into the "properties" `Map` of `ProblemDetail`. When using the Jackson
|
||||
|
||||
|
||||
[[mvc-ann-rest-exceptions-non-standard]]
|
||||
=== Non-Standard Fields
|
||||
[.small]#<<web-reactive.adoc#webflux-ann-rest-exceptions-non-standard, WebFlux>>#
|
||||
|
||||
You can extend an RFC 7807 response with non-standard fields in one of two ways.
|
||||
|
||||
One, insert into the "properties" `Map` of `ProblemDetail`. When using the Jackson
|
||||
library, the Spring Framework registers `ProblemDetailJacksonMixin` that ensures this
|
||||
"properties" `Map` is unwrapped and rendered as top level JSON properties in the
|
||||
response, and likewise any unknown property during deserialization is inserted into
|
||||
this `Map`.
|
||||
- Extend `ProblemDetail` to add dedicated non-standard properties. The copy constructor
|
||||
in `ProblemDetail` allows a sub-class to make it easy to be created from an existing
|
||||
`ProblemDetail`. This could be done centrally, e.g. from an `@ControllerAdvice` such as
|
||||
`ResponseEntityExceptionHandler` that re-creates the `ProblemDetail` of an exception into
|
||||
a subclass with the additional non-standard fields.
|
||||
|
||||
You can also extend `ProblemDetail` to add dedicated non-standard properties.
|
||||
The copy constructor in `ProblemDetail` allows a sub-class to make it easy to be created
|
||||
from an existing `ProblemDetail`. This could be done centrally, e.g. from an
|
||||
`@ControllerAdvice` such as `ResponseEntityExceptionHandler` that re-creates the
|
||||
`ProblemDetail` of an exception into a subclass with the additional non-standard fields.
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-rest-exceptions-i8n]]
|
||||
=== Internationalization
|
||||
[.small]#<<web-reactive.adoc#webflux-ann-rest-exceptions-i8n, WebFlux>>#
|
||||
|
||||
It is a common requirement to internationalize error response details, and good practice
|
||||
to customize the problem details for Spring MVC exceptions. This is supported as follows:
|
||||
|
||||
- Each `ErrorResponse` exposes a message code and message code arguments to resolve the
|
||||
problem "detail" field through a <<core.adoc#context-functionality-messagesource,MessageSource>>.
|
||||
The actual message code value is parameterized with placeholders, e.g.
|
||||
`"HTTP method {0} not supported"` to be expanded from the arguments.
|
||||
- `ResponseEntityExceptionHandler` uses the message code and the message arguments
|
||||
to resolve the problem "detail" field.
|
||||
|
||||
Message codes default to "problemDetail." + the fully qualified exception class name. Some
|
||||
exceptions may expose additional message codes in which case a suffix is added to
|
||||
the default message code. The table below lists message arguments and codes for Spring
|
||||
MVC exceptions:
|
||||
|
||||
[[mvc-ann-rest-exceptions-codes]]
|
||||
[cols="1,1,2", options="header"]
|
||||
|===
|
||||
| Exception | Message Code | Message Code Arguments
|
||||
|
||||
| `AsyncRequestTimeoutException`
|
||||
| (default)
|
||||
|
|
||||
|
||||
| `HttpMediaTypeNotAcceptableException`
|
||||
| (default)
|
||||
| `{0}` list of supported media types
|
||||
|
||||
| `HttpMediaTypeNotAcceptableException`
|
||||
| (default) + ".parseError"
|
||||
|
|
||||
|
||||
| `HttpMediaTypeNotSupportedException`
|
||||
| (default)
|
||||
| `{0}` the media type that is not supported, `{1}` list of supported media types
|
||||
|
||||
| `HttpMediaTypeNotSupportedException`
|
||||
| (default) + ".parseError"
|
||||
|
|
||||
|
||||
| `HttpRequestMethodNotSupportedException`
|
||||
| (default)
|
||||
| `{0}` the current HTTP method, `{1}` the list of supported HTTP methods
|
||||
|
||||
| `MethodArgumentNotValidException`
|
||||
| (default)
|
||||
| `{0}` the list of global errors, `{1}` the list of field errors.
|
||||
Message codes and arguments for each error within the `BindingResult` are also resolved
|
||||
via `MessageSource`.
|
||||
|
||||
| `MissingRequestHeaderException`
|
||||
| (default)
|
||||
| `{0}` the header name
|
||||
|
||||
| `MissingServletRequestParameterException`
|
||||
| (default)
|
||||
| `{0}` the request parameter name
|
||||
|
||||
| `MissingMatrixVariableException`
|
||||
| (default)
|
||||
| `{0}` the matrix variable name
|
||||
|
||||
| `MissingPathVariableException`
|
||||
| (default)
|
||||
| `{0}` the path variable name
|
||||
|
||||
| `MissingRequestCookieException`
|
||||
| (default)
|
||||
| `{0}` the cookie name
|
||||
|
||||
| `MissingServletRequestPartException`
|
||||
| (default)
|
||||
| `{0}` the part name
|
||||
|
||||
| `NoHandlerFoundException`
|
||||
| (default)
|
||||
|
|
||||
|
||||
| `UnsatisfiedServletRequestParameterException`
|
||||
| (default)
|
||||
| `{0}` the list of parameter conditions
|
||||
|
||||
|===
|
||||
|
||||
|
||||
|
||||
[[mvc-ann-rest-exceptions-client]]
|
||||
=== Client Handling
|
||||
[.small]#<<web-reactive.adoc#webflux-ann-rest-exceptions-client, WebFlux>>#
|
||||
|
||||
A client application can catch `WebClientResponseException`, when using the `WebClient`,
|
||||
or `RestClientResponseException` when using the `RestTemplate`, and use their
|
||||
|
||||
Reference in New Issue
Block a user