简体   繁体   中英

Spring REST Controller Unsupported Media Type or No Handler

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM