Таким образом, ответ, который я решил, основан на том, что Джексон не поддерживает нестандартные коллекции из коробки.Само собой разумеется, что только наборы java sdk будут работать из коробки.
Так что я закончил тем же, что и Spring Security, с нестандартными коллекциями, которые он добавляет.
context.setMixInAnnotations(Collections.<Object>unmodifiableSet(Collections.emptySet()).getClass(), UnmodifiableSetMixin.class);
(из org.springframework.security.jackson2.CoreJackson2Module)
Итак, я сделал то же самое:
context.setMixInAnnotations(org.apache.openjpa.util.java$util$LinkedHashSet$proxy.class, OpenJpaLinkedHashSetProxyMixin.class);
Это означает, что я могу настроить, как Джексон обращается с этим классом.
Теперь Джексон сериализует эту коллекцию без проблем.Проблема когда-либо была с сериализацией.Джексон, кажется, поддерживает любой подкласс Set, когда дело доходит до сериализации.Он борется за десериализацию.
То, что делает Spring, - это предоставление собственного десериализатора для этого неизменяемого набора, и это, кажется, единственный способ пойти с этим.
Итак, миксин:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonDeserialize(using = Deserializer.class)
public static class OpenJpaLinkedHashSetProxyMixin {
}
Если на десериализаторе вносятся незначительные изменения, скопированные с
org.springframework.security.jackson2.UnmodifiableSetDeserializer
и это:
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);
}
}
Например, я просто возвращаю хэш-набор напрямую (без включения его в неизменяемый набор).
Я думаю, суть в том, что мне не нужно, чтобы сериализованный набор возвращался обратно втот же класс, из которого он получен (org.apache.openjpa.util.java $ util $ LinkedHashSet $ proxy), поэтому, если это Set, не имеет значения, какая реализация.В этом случае я думаю, что реализация - это HashSet.
И я подозреваю, что это рекомендуемый / единственный способ успешно десериализовать коллекции, которые Джексон не поддерживает "из коробки".