Невозможно десериализовать экземпляр MyEnum из токена START_OBJECT - PullRequest
0 голосов
/ 16 мая 2019

Застрял в проблеме десериализации перечисления MyEnum из JSON в POJO и не могу понять, что я делаю неправильно.Поэтому в основном я пытаюсь получить некоторые данные, вызывающие конкретную конечную точку микросервиса, которая возвращает следующий json:

    {
      "id": "9cabf3e9-965d-4407-b62b-c57dd6006419",
      "myEnums": [
        {
          "context": "SOME_FOO_CONTEXT_1",
          "feature": "SOME_BAR_FEATURE_1",
          "name": "SOME_FOO_BAR_1"
        },
        {
          "context": "SOME_FOO_CONTEXT_2",
          "feature": "SOME_BAR_FEATURE_2",
          "name": "SOME_FOO_BAR_2"
        }
      ],
      "name": "Some name",
      "updatedBy": null,
      "updated": "2019-05-16T00:11:19.279Z"
    }

Это метод, который вызывает другую конечную точку микросервиса, десериализует тело ответа в POJO и возвращает результат в виде Set:

      private Mono<Set<MyEnum>> fetchMyEnums(UUID someId) {
            return webClient.get().uri("/v1/something/{id}", someId)
                            .retrieve()
                            .bodyToMono(MyClass.class)
                            .flatMapIterable(MyClass::getMyEnums)
                            .collect(toSet());
        }

Класс, используемый для десериализации JSON:

    @lombok.Value
    static class MyClass {

        List<MyEnum> myEnums;

    }

Перечислите, что я на самом деле не могу десериализовать:

    @Getter
    @RequiredArgsConstructor
    @AllArgsConstructor
    @JsonFormat(shape = JsonFormat.Shape.OBJECT)
    public enum MyEnum {

        SOME_FOO_BAR_1(SOME_FOO_CONTEXT_1, SOME_BAR_FEATURE_1),
        SOME_FOO_BAR_2(SOME_FOO_CONTEXT_2, SOME_BAR_FEATURE_2);

        private final FooEnum context;
        private final BarEnum feature;
        private       String  name;

        @JsonProperty
        public String getName() {
            return super.name();
        }

    }

Во время десериализации я получаю следующее исключение:

    org.springframework.core.codec.DecodingException: JSON decoding error: Cannot deserialize instance of `com.learn.common.security.model.MyEnum` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.learn.common.security.model.MyEnum` out of START_OBJECT token
     at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.learn.common.security.service.MyEnumService$MyClass["myEnums"]->java.util.ArrayList[0])

Где я ошибся?

1 Ответ

0 голосов
/ 17 мая 2019

Поэтому потратив еще несколько часов, чтобы выяснить, в чем проблема с десериализацией, я выяснил, что для Enum, чей Shape.Object не существует автоматической десериализации.

Но я нашел обходной путь, как десериализовать объект MyEnum из json (вам нужно определить статический метод, помеченный как JsonCreator, и определить, какой входной параметр вы ожидаете получить от объекта, определяющего JsonProperty с помощью fieldName):

@Getter
@RequiredArgsConstructor
@AllArgsConstructor
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {

    SOME_FOO_BAR_1(SOME_FOO_CONTEXT_1, SOME_BAR_FEATURE_1),
    SOME_FOO_BAR_2(SOME_FOO_CONTEXT_2, SOME_BAR_FEATURE_2);

    private final FooEnum context;
    private final BarEnum feature;
    private       String  name;

    @JsonProperty
    public String getName() {
        return super.name();
    }

    @JsonCreator
    public static Permission fromJson(@JsonProperty("name") String name) {
        return valueOf(name);
    }

}
...