(De)序列化枚举集

时间:2015-05-14 19:36:40

标签: java enums jackson enumset

是否有一种简单的方法可以使用Jackson序列化和反序列化枚举集?

    ManualViewController *controller = [ManualViewController new];
    [controller setDocumentID: [[[self fetchedResultsController] objectAtIndexPath: indexPath] objectID]];
    [controller setShowsDoneButton: YES];
    [controller setDelegate: self];    

    NavigationController *navController = [[NavigationController alloc] initWithRootViewController: controller];
    [navController setModalPresentationStyle: UIModalPresentationPageSheet];
    [navController setModalTransitionStyle: UIModalTransitionStyleCoverVertical];
    [navController setShouldAutorotate: YES];
    [navController setSupportedInterfaceOrientations: UIInterfaceOrientationMaskAll];
    [self presentViewController: navController animated: YES completion: nil];

这给出了以下XML:

private enum Type {
    YES, NO
}

@JacksonXmlProperty(localName = "type", isAttribute = true)
private final EnumSet<Type> types;

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

我还尝试了以下注释:

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

但这会产生以下错误:

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

1 个答案:

答案 0 :(得分:1)

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

@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]}