Завершение ответа об ошибке REST по умолчанию в пользовательский объект - PullRequest
0 голосов
/ 31 августа 2018

Я создаю простой REST API для интеграции, и я хочу, чтобы ответ был максимально последовательным (одинаковым независимо от ошибок).

Я использовал метод @ExceptionHandler в прошлом - так что я, скорее всего, пойду с классовой версией этого ... @ControllerAdvice, если я правильно помню.

Я знаю, что это работает, я использовал SO прежде, чтобы помочь мне, просто требует настройки. Это не мой вопрос ...

API позволяет создавать сообщения и искать сообщения (два отдельных запроса) и, таким образом, принимает значения дат, которые внутренне проверены. После тестирования я получил очень хорошо отформатированный и невероятно подробный ответ об ошибке:

{
    "timestamp": "2018-08-31T10:35:10.748+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "typeMismatch.IntegrationMessageFilter.fromDate",
                "typeMismatch.fromDate",
                "typeMismatch.java.util.Date",
                "typeMismatch"
            ],
            "arguments": [
                {
                    "codes": [
                        "IntegrationMessageFilter.fromDate",
                        "fromDate"
                    ],
                    "arguments": null,
                    "defaultMessage": "fromDate",
                    "code": "fromDate"
                }
            ],
            "defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'fromDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat java.util.Date] for value '213-456-45'; nested exception is java.lang.IllegalArgumentException",
            "objectName": "IntegrationMessageFilter",
            "field": "fromDate",
            "rejectedValue": "213-456-45",
            "bindingFailure": true,
            "code": "typeMismatch"
        }
    ],
    "message": "Validation failed for object='IntegrationMessageFilter'. Error count: 1",
    "path": "/Integration/get"
}

Что я хочу сделать, так это перехватить эту ошибку и обернуть ее в свой собственный объект ответа, который будет одинаковым объектом ответа для каждого доступного метода API : например, * 1 016 *

{
    "success": Boolean,
    "messageId": Integer, (null on search, int on successful create)
    "messages": Array, (searched IntegrationMessage objects)
    "errorMessage": String, (error message during manual validation (e.g. range validation depending on the field))
    "error" [SPRING DEFAULT ERROR] (this is what i want to intercept from spring-boot and include in this response object)
}

Он просто видит немного бессмысленным ручную ошибку при создании подробного сообщения об ошибке, когда система уже делает это ... Я не знаю, какой объект он использует для создания первого сообщения JSON выше, или даже если я могу перехватить это.

ПРИМЕЧАНИЕ: Это просто для удобства пользователей API, которым не нужно делать различий между различными объектами ответа, и для удобства, для меня нет необходимости заново разрабатывать колесо (так сказать).

1 Ответ

0 голосов
/ 31 августа 2018

ОК, так что я нашел, как добиться (вроде) того, что я хочу.

У меня сложилось впечатление, что я могу перехватить полное ответное сообщение об исключении и просто поместить его в свой объект, независимо от типа исключения. Оказывается, я могу получить большинство информации по умолчанию, но она специфична для каждого типа ошибок (очевидно).

Первая попытка:
Моя первая попытка состояла в том, чтобы просто «проверить» ответ ошибки по умолчанию со следующим. Это было предназначено для определения того, что делал Spring (какую ошибку он использовал - я думал, что это было бы исключение handleTypeMismatch) - метод, приведенный ниже, - только один в классе (тот, с которым я сейчас имею дело) :

@ControllerAdvice
public class IntegrationExceptionHandler extends ResponseEntityExceptionHandler
{
    @Override
    public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
    {
        return super.handleBindException(ex, headers, status, request);
    }
}

Я ожидал, что сообщение об ошибке будет точно таким же, как и сообщение по умолчанию, однако это не привело к ответу (или пустому ответу?).

Мое "решение":
Хотя мне не нужно заново разрабатывать колесо, я должен совершить прыжок с обручем:

    @Override
    public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
    {               

        IntegrationResponse response = new IntegrationResponse(ex.getMessage());
        response.setErrors(ex.getBindingResult().getAllErrors());

        return new ResponseEntity<Object>(response, headers, status);
    }

Где ошибки private List<ObjectError> errors; (org.springframework.validation.ObjectError)

Так что мне придется попытаться повторить каждую переопределяемую ошибку в ResponseEntityExceptionHandler (что относится к моей ситуации) и обработать ее немного по-другому, теперь вы можете понять, почему я просто хотел обернуть существующий ответ .

Так же, как примечание, я попытался добавить: private Object error; и private BindingResult error; в качестве переменных в моем объекте ответа, однако обе попытки, по-видимому, отклоняют мой объект ответа и показывают ПРОСТО сообщение по умолчанию (как если бы не было контроллера совет) без намека на то, почему.

Если кто-нибудь обнаружит, как пропустить шаг ResponseEntityExceptionHandler и просто обернуть объект ответа исключения по умолчанию, я с радостью приму этот ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...