Spring REST Controller Неподдерживаемый тип носителя или нет обработчика

Если у меня есть контроллер Spring REST, подобный этому

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

и клиент вызывает эту конечную точку с неправильным типом носителя в заголовке Accept, тогда spring выдает HttpMediaTypeNotAcceptableException. Затем наш обработчик исключений ловит это и формирует ответ об ошибке Problem (rfc-7807).

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

Но поскольку ответ об ошибке Problem должен быть отправлен обратно с типом носителя application/problem+json, то Spring считает это неприемлемым типом носителя и снова вызывает обработчик исключений HttpMediaTypeExceptionHandler и говорит, что тип носителя недопустим.

Есть ли способ в Spring остановить этот второй цикл в обработчике исключений, и хотя заголовок accept не включает тип мультимедиа application/problem+json, он все равно просто вернет его?

0
0
449
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как ни странно, он начал работать, когда я изменил оператор return с этого:

return new ResponseEntity<>(problem, httpStatus);

к этому:

return ResponseEntity
        .status(httpStatus)
        .contentType(MediaType.APPLICATION_PROBLEM_JSON)
        .body(problem);

Я не уверен, как это заставляет это работать, но это работает.

Другие вопросы по теме