Пользовательский ответ на ошибку загрузки Spring при недопустимом запросе

У меня есть приложение весенней загрузки, реализующее REST API. У меня есть конечная точка POST, которая получает объект через @RequestBody, этот объект имеет несколько полей, некоторые из которых имеют тип Long среди них. Проблема, с которой я сталкиваюсь, заключается в том, что когда я получаю недопустимую полезную нагрузку запроса, содержащую буквенную строку в качестве значения для поля типа long, приложение возвращает ответ HTTP 400 с пустой полезной нагрузкой, но я хотел бы иметь возможность чтобы настроить этот ответ (например, через @ControllerAdvice) и предоставить описание ошибки. Однако до сих пор мне это не удавалось.

Объект полезной нагрузки запроса:

public final class ExchangeRateDTO {
    public final Long provider;
    public final String from;
    public final String to;
    public final BigDecimal amount;
    public final String date;

    public ExchangeRateDTO(Long provider, String from, String to, BigDecimal amount, String date) {
        this.provider = provider;
        this.from = from;
        this.to = to;
        this.amount = amount;
        this.date = date;
    }
}

Контроллер:

@RestController
@RequestMapping("/v1/exchangerate")
public class ExchangeRateController {
    private CommandBus commandBus;

    @Autowired
    public ExchangeRateController(CommandBus commandBus) {
        this.commandBus = commandBus;
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    @Loggable(operationName = "AddExchangeRateRequest")
    public void create(@RequestBody ExchangeRateDTO exchangeRate) {
        commandBus.dispatch(new AddExchangeRateCommand(exchangeRate.provider, exchangeRate.from, exchangeRate.to, exchangeRate.amount, exchangeRate.date));
    }
}

Класс ControllerAdvice:

@RestControllerAdvice
public class ExchangeRateStoreExceptionHandler extends ResponseEntityExceptionHandler {
    private ErrorResponseAdapter errorResponseAdapter;
    private ErrorStatusAdapter errorStatusAdapter;

    public ExchangeRateStoreExceptionHandler() {
        this.errorResponseAdapter = new ErrorResponseAdapter();
        this.errorStatusAdapter = new ErrorStatusAdapter();
    }

    @ExceptionHandler({ValidationError.class})
    protected ResponseEntity<ValidationErrorResponse> handleValidationError(ValidationError error) {
        ValidationErrorResponse errorResponse = errorResponseAdapter.fromValidationError(error);
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler({DomainError.class})
    protected ResponseEntity<ErrorResponse> handleDomainError(DomainError error) {
        ErrorResponse errorResponse = errorResponseAdapter.fromDomainError(error);
        HttpStatus errorStatus = errorStatusAdapter.fromDomainError(error);
        return new ResponseEntity<>(errorResponse, errorStatus);
    }

    @ExceptionHandler({Exception.class})
    protected ResponseEntity<ErrorResponse> handleAllOtherExceptions(Exception exception) {
        String message = "There was an unexpected error. Please retry later.";
        ErrorResponse errorResponse = new ErrorResponse(INTERNAL.toString(), message);
        return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

Запрос образца:

curl -vX POST http://localhost:8081/v1/exchangerate \
  -H 'Content-Type: application/json' \
  -d '{
    "provider": 1,
    "from": "USD",
    "to": "EUR",
    "amount": "as",
    "date": "2018-11-22T00:00:00Z"
}'

И его ответ:

< HTTP/1.1 400
< Content-Length: 0
< Date: Mon, 11 Mar 2019 16:53:40 GMT
< Connection: close

Есть идеи?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
4 081
1

Ответы 1

Вы уже расширяете ResponseEntityExceptionHandler, поэтому все, что вам нужно, это просто метод @OverrideдескрипторHttpMessageNotReadable:

@ControllerAdvice
public class ExchangeRateStoreExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        return new ResponseEntity<>(ex.getLocalizedMessage(), status);
    }

}

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