Как настроить Джексона для десериализации специальных коллекций? - PullRequest
0 голосов
/ 06 ноября 2019

Мне интересно, как настроить Джексона для десериализации сериализованного списка объектов, которые содержались в «специальных» коллекциях (неизменяемых или в результате собранного потока).

Вот моя проблема, по определенным причинамМне нужно объявить де-печатание в Джексоне, потому что я должен быть в состоянии десериализовать все и вернуть все мои типы.


public static class Sink {
    private List items;

    public Sink setItems(final List items) {
        this.items = items;
        return this;
    }

    public List getItems() {
        return this.items;
    }
}

public static void main(String[] args) throws Exception {
    final ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new AfterburnerModule());
    mapper.enableDefaultTyping(NON_FINAL, JsonTypeInfo.As.PROPERTY);

    String content = mapper.writeValueAsString(new Sink().setItems(List.of()));
    System.out.println(content);
    Sink result = mapper.readValue(content, Sink.class);
}

Но это имеет неприятный побочный эффект с коллекциями. Значение content:

{
    "@class": "api.Sink",
    "items": ["java.util.ImmutableCollections$ListN", []]
}

И, к сожалению, java.util.ImmutableCollections.* не имеет конструкторов по умолчанию (что имеет смысл).

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of java.util.ImmutableCollections $ ListN(no Creators, like default construct, exist): no default no-arguments constructor found

Мне интересно, как заставить Джексона десериализовать объект такого типа как ArrayList или любой другой тип списка.

Я бы хотел настроить его для десериализации всех подтиповсписка как ArrayList / LinkedList или при сериализации для изменения типа коллекции

(java 12 / jackson 2.9.7)

1 Ответ

1 голос
/ 06 ноября 2019

Вы можете расставить точки, используя определенный десериализатор, как описано, например, в Mixin.

Пример десериализатора:

class UnmodifiableSetDeserializer extends JsonDeserializer<Set> {

@Override
public Set deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    ObjectMapper mapper = (ObjectMapper) jp.getCodec();
    JsonNode node = mapper.readTree(jp);
    Set<Object> resultSet = new HashSet<Object>();
    if (node != null) {
        if (node instanceof ArrayNode) {
            ArrayNode arrayNode = (ArrayNode) node;
            Iterator<JsonNode> nodeIterator = arrayNode.iterator();
            while (nodeIterator.hasNext()) {
                JsonNode elementNode = nodeIterator.next();
                resultSet.add(mapper.readValue(elementNode.traverse(mapper), Object.class));
            }
        } else {
            resultSet.add(mapper.readValue(node.traverse(mapper), Object.class));
        }
    }
    return Collections.unmodifiableSet(resultSet);
}
}

Полный пример вы можете найти в CoreJacksont2Module of Springбезопасность здесь

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