У меня есть приложение весенней загрузки, реализующее 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
Есть идеи?




Вы уже расширяете 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);
}
}