Reputation: 2095
If I have a spring REST controller like this
@PostMapping(
value = "/configurations",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public CreateConfigurationResponse createConfiguration(
@RequestBody @Valid @NotNull final CreateConfigurationRequest request) {
// do stuff
}
and a client calls this endpoint with the wrong media type in the Accept
header then spring throws a HttpMediaTypeNotAcceptableException
. Then our exception handler catches that and constructs a Problem
(rfc-7807) error response
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class HttpMediaTypeExceptionHandler extends BaseExceptionHandler {
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public ResponseEntity<Problem> notAcceptableMediaTypeHandler(final HttpMediaTypeNotAcceptableException ex,
final HttpServletRequest request) {
final Problem problem = Problem.builder()
.withType(URI.create("...."))
.withTitle("unsupported media type")
.withStatus(Status.NOT_ACCEPTABLE)
.withDetail("...error stuff..")
.build();
return new ResponseEntity<>(problem, httpStatus);
}
But since the Problem
error response should be sent back with a media type application/problem+json
spring then sees that as not acceptable media type and calls the HttpMediaTypeExceptionHandler
exception handler again and says that media type is not acceptable.
Is there a way in Spring to stop this second loop into the exception handler and even though the accept header didn't include the application/problem+json
media type it will just return that anyway?
Upvotes: 1
Views: 1153
Reputation: 2095
So strangely it started working when I changed the return statement from this:
return new ResponseEntity<>(problem, httpStatus);
to this:
return ResponseEntity
.status(httpStatus)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(problem);
I'm not sure how this makes it work but it does.
Upvotes: 1