(de)序列化枚举集



是否有一种简单的方法可以与杰克逊序列化和挑选枚举集?

private enum Type {
    YES, NO
}
@JacksonXmlProperty(localName = "type", isAttribute = true)
private final EnumSet<Type> types;

这给出以下XML:

...<type type="YES" type="NO"/>...

此XML无效,因为有重复属性。

我也尝试了以下注释:

@JsonSerialize(using = EnumSetSerializer.class)
@JacksonXmlProperty(localName = "type", isAttribute = true)
private final EnumSet<Type> mTypes;

但这给出以下错误:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Class com.fasterxml.jackson.databind.ser.std.EnumSetSerializer has no default (no arg) constructor

在这种情况下,您应该编写一个自定义的EnumSet序列化器/Deserializer,将枚举设置转换为字符串。这是一个完整的示例:

@SuppressWarnings({"unchecked", "raw"})
public class JacksonEnumSet {
    public enum Type {
        YES, NO
    }
    public static class Bean {
        @JacksonXmlElementWrapper(useWrapping = false)
        @JacksonXmlProperty(localName = "type", isAttribute = true)
        @JsonSerialize(using = EnumSetSerializer.class)
        @JsonDeserialize(using = EnumSetDeserializer.class)
        private final EnumSet<Type> types;
        @JsonCreator
        public Bean(@JsonProperty("type") final EnumSet<Type> types) {this.types = types;}
        public EnumSet<Type> getTypes() {return types;}
        @Override
        public String toString() {
            return "Bean{" +
                    "types=" + types +
                    '}';
        }
    }
    public static class EnumSetSerializer extends JsonSerializer<EnumSet> {
        @Override
        public void serialize(
                final EnumSet value,
                final JsonGenerator gen,
                final SerializerProvider serializers)
                throws IOException {
            final StringBuilder builder = new StringBuilder();
            for (final Object e : value) {
                if (builder.length() > 0) {
                    builder.append(";");
                }
                builder.append(e);
            }
            gen.writeString(builder.toString());
        }
    }
    public static class EnumSetDeserializer extends JsonDeserializer<EnumSet>
        implements ContextualDeserializer {
        private Class enumType;
        @Override
        public EnumSet deserialize(
                final JsonParser p,
                final DeserializationContext ctxt) throws IOException {
            final String string = p.getValueAsString();
            final EnumSet enumSet = EnumSet.noneOf(enumType);
            for (final String name : string.split(";")) {
                enumSet.add(Enum.valueOf(enumType, name));
            }
            return enumSet;
        }
        @Override
        public JsonDeserializer<?> createContextual(
                final DeserializationContext ctxt, final BeanProperty property)
                throws JsonMappingException {
            final CollectionLikeType type = (CollectionLikeType)property.getType();
            final EnumSetDeserializer enumSetDeserializer = new EnumSetDeserializer();
            enumSetDeserializer.enumType = type.getContentType().getRawClass();
            return enumSetDeserializer;
        }
    }
    public static void main(String[] args) throws IOException {
        final XmlMapper mapper = new XmlMapper();
        final Bean bean = new Bean(EnumSet.allOf(Type.class));
        final String xml = mapper.writeValueAsString(bean);
        System.out.println(xml);
        System.out.println(mapper.readValue(xml, Bean.class));
    }
}

输出:

<Bean xmlns="" type="YES;NO"></Bean>
Bean{types=[YES, NO]}

相关内容

  • 没有找到相关文章

最新更新