Как игнорировать информацию о типе массивов json при десериализации Джексона? - PullRequest
2 голосов
/ 26 марта 2019

Я бы хотел перенести мою конфигурацию ObjectMapper с той, которая включает информацию о типе, на ту, которая не содержит.

В настоящее время мой ObjectMapper настроен так:

ObjectMapper objectMapper = new ObjectMapper().enableDefaultTypingAsProperty(
  ObjectMapper.DefaultTyping.NON_FINAL, 
  "@class"
);

Какаяпозволяет мне десериализовать объекты json, которые выглядят следующим образом:

{
  "@class": "com.foo.BarClass",
  "barProp": "bar"
  "barList": [
    [
      "java.util.ArrayList",
      [
        { "@class": "com.foo.BarListElement", ... },
        { "@class": "com.foo.BarListElement", ... },
        ...
      ]
  ],
  ...
}

со следующим POJO:

public class BarClass {
  private String barProp;
  // assume BarListElement to be a POJO with sensible getters/setters
  List<BarListElement> barList;
  // assume some other trivial fields and corresponding getters/setters
}

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

Я попытался добиться этого, удалив вызов enableDefaultTypingAsProperty и вместо этого вызвав configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) в ObjectMapper,с намерением игнорировать свойство "@class", присутствующее в json.К сожалению, это работает только для json, который не содержит массивов, так как массив json, который я получаю, содержит конкретную информацию о типе List (т.е. элемент "java.util.ArrayList" в массиве в примере).

Я бы хотелспросите, есть ли способ настроить ObjectMapper таким образом, чтобы тип коллекции в массиве json также игнорировался.

1 Ответ

1 голос
/ 27 марта 2019

Вам необходимо настроить десериализатор коллекции, который позаботится о дополнительной информации о типе.Массив с типом имеет общую структуру: ["java.util.collectionType", [...]].Для этого нам нужно использовать BeanDeserializerModifier и пользовательские CollectionDeserializer.Давайте начнем с пользовательского десериализатора:

class OmitListTypeJsonDeserializer extends CollectionDeserializer {

    public OmitListTypeJsonDeserializer(CollectionDeserializer src) {
        super(src);
    }

    @Override
    public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        p.nextToken(); // Omit array type
        p.nextToken(); // Omit comma and start array

        Collection<Object> collection = super.deserialize(p, ctxt);

        p.nextToken(); // Omit end of array

        return collection;
    }

    @Override
    public CollectionDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        return new OmitListTypeJsonDeserializer(super.createContextual(ctxt, property));
    }
}

Модификатор десериализатора бина выглядит следующим образом:

class OmitListTypeDeserializerModifier extends BeanDeserializerModifier {

    @Override
    public JsonDeserializer<?> modifyCollectionDeserializer(DeserializationConfig config, CollectionType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
        if (deserializer instanceof CollectionDeserializer) {
            return new OmitListTypeJsonDeserializer((CollectionDeserializer) deserializer);
        }

        return deserializer;
    }
}

Пример использования:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.std.CollectionDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper typeAwareMapper = new ObjectMapper();
        typeAwareMapper.enable(SerializationFeature.INDENT_OUTPUT);
        typeAwareMapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.NON_FINAL, "@class");

        String json = typeAwareMapper.writeValueAsString(new BarClass());
        System.out.println(json);

        SimpleModule module = new SimpleModule();
        module.setDeserializerModifier(new OmitListTypeDeserializerModifier());

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        System.out.println(mapper.readValue(json, BarClass.class));
    }
}

class BarClass {
    private String barProp = "PROP1";
    private List<BarListElement> barList = Arrays.asList(new BarListElement(), new BarListElement());
    private Integer zet = 123;

    // getters, setters
}

class BarListElement {

    private Double sid = Math.random();

    // getters, setters
}

Над кодом печатается ниже JSON:

{
  "@class" : "com.celoxity.BarClass",
  "barProp" : "PROP1",
  "barList" : [ "java.util.Arrays$ArrayList", [ {
    "@class" : "com.celoxity.BarListElement",
    "sid" : 0.09525693290513237
  }, {
    "@class" : "com.celoxity.BarListElement",
    "sid" : 0.689909415561781
  } ] ],
  "zet" : 123
}

и десериализованный объект:

BarClass{barProp='PROP1', barList=[BarListElement{sid=0.09525693290513237}, BarListElement{sid=0.689909415561781}], zet=123}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...