Как разобрать пустое значение "{}" (в строку) - PullRequest
0 голосов
/ 30 января 2019

Учитывая json:

{
  "name" : {}
}

Я бы хотел разобрать его в следующий Java-объект, используя com.fasterxml.jackson:

class MyClass {
  private String name;
}

Если вы попробуете это, вы получите:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

Есть ли способ настроить десериализатор Джексона (глобально для лучшего), он может обрабатывать эти empty objects как nulls без изменения типа атрибута (из строки)?

Ответы [ 3 ]

0 голосов
/ 30 января 2019

В json {} - это Object, что означает, что он может иметь поля (например, POJO в Java).Когда вы пытаетесь десериализовать его в String, он генерирует исключение (представьте, что вы пытаетесь присвоить POJO для ссылки на строку в Java).

В этом случае есть две опции:

  • Настройте свой класс так, чтобы он не включал пустые поля.Это можно сделать с помощью аннотации или конфигурации в вашем экземпляре ObjectMapper, например:

    @JsonInclude(Include.NON_NULL)
    class MyClass {
      private String name;
    }
    

    ИЛИ

    mapper.setSerializationInclusion(Include.NON_EMPTY);

    Эта опция может не работать, если ответне имеет значения nameЕсли это объект с ненулевым значением, Джексон попытается десериализовать его в String и потерпит неудачу.

  • Измените тип name на Object (или, скорее,POJO со всеми элементами, которые может содержать ответ).Это, однако, означает, что вам нужно изменить код, который обращается к элементу name, так как он больше не будет String.

0 голосов
/ 30 января 2019

Нет необходимости писать собственный десериализатор, вам просто нужно инкапсулировать ваш объект имени в классе, и он работает:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "name"
})
public class JsonExample {
        @JsonProperty("name")
        public Name name;
}

и

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "first",
        "last"
})
public class Name {
    @JsonProperty("first")
    public String first_name;
    @JsonProperty("last")
    public String last_name;
}

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

JsonExample obj = mapper.readValue(file, JsonExample.class);
0 голосов
/ 30 января 2019

Для этого вы можете написать свой собственный десериализатор.После this вы расширяете StdDeserializer и регистрируете его в классе.


Автор редактора:

Я использовал следующий десериализатор для строки работает нормально, спасибо:

public class EmptyObjectDeserializer extends StdDeserializer<String> {

    public EmptyObjectDeserializer() {
        this(null);
    }

    public EmptyObjectDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        return node.asText("");
    }
}
...