首页 > 解决方案 > 将 JSON 对象反序列化为 java.util.Set

问题描述

如何将 JSON 对象序列化为自定义 java.util.Set?

考虑这段代码:

@JsonSerialize(using = SingleSetSerializer.class)
public class SingleSet<Key> implements Set<Key> {
    private Set<Key> keys = new HashSet<Key>();

    public SingleSet(Key key) {
        this.keys = new HashSet<Key>( new ArrayList<Key>(Collections.nCopies(1, key)));
    }
}

使用此序列化程序:

public class SingleSetSerializer extends StdSerializer<SingleSet> {
    public SingleSetSerializer() {
        this(null);
    }

    protected SingleSetSerializer(Class<SingleSet> t) {
        super(t);
    }

    @Override
    public void serialize(SingleSet value,
                          JsonGenerator gen,
                          SerializerProvider provider) throws IOException {
        Object obj  = value.iterator().next();
        if(Objects.nonNull(obj)) {
            if(Key.class.isAssignableFrom(obj.getClass())) {
                Key key = (Key) obj;
                gen.writeStartObject();
                gen.writeStringField("entityType", key.getEntityType());
                gen.writeStringField("entityId", key.getEntityId());
                gen.writeEndObject();
            } else {
                throw new IllegalArgumentException("Type not supported: " + obj.getClass());
            }
        }
    }
}

序列化工作正常,但问题是反序列化无法将 JSON 对象处理为 a SingleSet,并抛出此错误:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.HashSet` out of START_OBJECT token
 at [Source: (String)"{"metaData":{"key":{"entityType":"Blog","entityId":"0-1"}},"properties":{"slug":{"stringValue":"a-blog"}},"links":{"next":{"entityType":"Blog","entityId":"0-2"},"previous":{"entityType":"Blog","entityId":"0-0"}}}"; line: 1, column: 123] (through reference chain: company.Entity["links"]->java.util.LinkedHashMap["next"])

    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1138)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1092)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:332)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:265)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:136)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)

标签: javajsonparsingjackson

解决方案


推荐阅读