【问题标题】:Jackson configuration to write enum as object杰克逊配置将枚举写为对象
【发布时间】:2012-01-06 00:26:44
【问题描述】:

当我尝试序列化和反序列化 Set<ClassA<?>> 的通用对象时,如下所示:

public class ClassA<T> {

private ClassB datum;
private T value;
...
}

如果 T 恰好是一个枚举,它会被写为一个字符串值。这对于序列化很好,但是当我反序列化时,无法知道字符串值是否为枚举。 Jackson 然后将生成的对象转换为字符串,您将得到 ClassA&lt;String&gt; 而不是 ClassA&lt;SomeEnumType&gt;

Jackson 中是否有配置让它创建一些值是枚举的提示?或者也许将枚举转换为 JSON 对象而不是字符串值?

【问题讨论】:

    标签: serialization enums deserialization jackson


    【解决方案1】:

    Jackson 中是否有配置让它创建一些值是枚举的提示?

    可以从匹配的 JSON 字符串值反序列化为枚举实例。或者这是否不适用于您的情况?

    这是一个例子。

    import java.util.Set;
    import java.util.TreeSet;
    
    import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
    import org.codehaus.jackson.annotate.JsonMethod;
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.type.TypeFactory;
    
    public class JacksonFoo
    {
      public static void main(String[] args) throws Exception
      {
        ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
    
        String myEnumJson = mapper.writeValueAsString(MyEnum.MyEnum1);
    
        System.out.println(myEnumJson);
    
        MyEnum myEnum = mapper.readValue(myEnumJson, MyEnum.class);
    
        System.out.println(myEnum);
    
        Set<ClassA<MyEnum>> set = new TreeSet<ClassA<MyEnum>>();
        set.add(new ClassA<MyEnum>(new ClassB("bValue7"), MyEnum.MyEnum1));
        set.add(new ClassA<MyEnum>(new ClassB("bValue8"), MyEnum.MyEnum2));
        String setJson = mapper.writeValueAsString(set);
        System.out.println(setJson);
    
        TypeFactory typeFactory = TypeFactory.defaultInstance();
    
        Set<ClassA<MyEnum>> setCopy = mapper.readValue(setJson,
            typeFactory.constructCollectionType(Set.class,
                typeFactory.constructParametricType(ClassA.class, MyEnum.class)));
        System.out.println(setCopy);
      }
    }
    
    class ClassA<T> implements Comparable<ClassA<T>>
    {
      ClassB datum;
      T value;
    
      ClassA()
      {
      }
    
      ClassA(ClassB datum, T value)
      {
        this.datum = datum;
        this.value = value;
      }
    
      @Override
      public int compareTo(ClassA<T> o)
      {
        return 42;
      }
    
      @Override
      public String toString()
      {
        return String.format("ClassA: datum=%s, value=%s", datum, value);
      }
    }
    
    class ClassB
    {
      String bValue;
    
      ClassB()
      {
      }
    
      ClassB(String bValue)
      {
        this.bValue = bValue;
      }
    
      @Override
      public String toString()
      {
        return String.format("ClassB: bValue=%s", bValue);
      }
    }
    
    enum MyEnum
    {
      MyEnum1("myEnum1", 1), MyEnum2("myEnum2", 2);
    
      String name;
      int id;
    
      MyEnum(String name, int id)
      {
        this.name = name;
        this.id = id;
      }
    }
    

    输出:

    "MyEnum1"
    MyEnum1
    [{"datum":{"bValue":"bValue7"},"value":"MyEnum1"},{"datum":{"bValue":"bValue8"},"value":"MyEnum2"}]
    [ClassA: datum=ClassB: bValue=bValue7, value=MyEnum1, ClassA: datum=ClassB: bValue=bValue8, value=MyEnum2]
    

    如果出于某种原因需要将枚举序列化为 POJO,则似乎需要自定义序列化处理。 Serializing enums with Jackson

    【讨论】:

    • 对于感兴趣的人,我记录了 Jackson 问题 725 来讨论和跟踪可能的增强功能,以便轻松配置(反)序列化枚举的状态。 jira.codehaus.org/browse/JACKSON-725如果您愿意,请投票和评论。
    • 谢谢 Bruce,我不知道 typeFactory.constructCollectionType 和 typeFactory.constructParametricType。这就是我一直在寻找的。​​span>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2014-08-01
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多