【问题标题】:How to instruct Jackson to serialize a field inside an Object instead of the Object it self?如何指示杰克逊序列化对象内部的字段而不是自身的对象?
【发布时间】:2012-06-17 08:51:09
【问题描述】:

我有一个Item 课程。该类中有一个 itemType 字段,其类型为 ItemType。

大概是这样的。

class Item
{
   int id;
   ItemType itemType;
}

class ItemType
{
   String name;
   int somethingElse;
}

当我使用 Jackson ObjectMapper 序列化 Item 类型的对象时,它会将对象 ItemType 序列化为子对象。这是预期的,但不是我想要的。

{
  "id": 4,  
  "itemType": {
    "name": "Coupon",
    "somethingElse": 1
  }
}

我想做的是在序列化时显示itemTypename 字段。

如下所示。

{
  "id": 4,  
  "itemType": "Coupon"
}

有没有办法指示杰克逊这样做?

【问题讨论】:

    标签: java serialization jackson


    【解决方案1】:

    查看@JsonValue 注释。

    编辑:像这样:

    class ItemType
    {
      @JsonValue
      public String name;
    
      public int somethingElse;
    }
    

    【讨论】:

    • 问题是“如何指示 Jackson 序列化 Object 内部的字段而不是 Object 本身?”这是通过使用 @JsonValue 注释所述字段来完成的。
    • 这是对原始问题的最佳答案,尽管 pingw33n 的回答实际上对我的情况有所帮助,这与此处的原始问题略有不同
    • @JsonValue 不能用于注释字段(至少在 2.6.7 版本中没有)。它有@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
    • 2.9及以上版本可用于注释字段
    • 对于超级懒惰的人(这可能是我自己在未来搜索这个 SO 答案):Javadocs 说 "标记注释,指示带注释的访问器的值(字段或“getter”方法[返回类型为非 void,无参数的方法]) 将用作实例序列化的单个值" fasterxml.github.io/jackson-annotations/javadoc/2.9/com/…
    【解决方案2】:

    您需要创建和使用custom serializer

    public class ItemTypeSerializer extends JsonSerializer<ItemType> 
    {
        @Override
        public void serialize(ItemType value, JsonGenerator jgen, 
                        SerializerProvider provider) 
                        throws IOException, JsonProcessingException 
        {
            jgen.writeString(value.name);
        }
    
    }
    
    @JsonSerialize(using = ItemTypeSerializer.class)
    class ItemType
    {
        String name;
        int somethingElse;
    }
    

    【讨论】:

    • 这行得通。为了完整起见,一个相​​关的可能性是让ItemType实现JsonSerializable(方法“serialize()”)。
    • 我不知道为什么我不能将序列化器声明为内部类,它总是给我一个错误。
    【解决方案3】:

    由于 OP 只想序列化一个字段,您也可以使用 @JsonIdentityInfo@JsonIdentityReference 注释:

    class Item {
        int id;
        @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="name")
        @JsonIdentityReference(alwaysAsId=true)
        ItemType itemType;
    }
    

    有关详细信息,请参阅How to serialize only the ID of a child with Jackson

    【讨论】:

    • 我认为这应该是公认的答案。它更简单,更优雅地解决了 OP 的问题。
    【解决方案4】:

    要返回简单的字符串,您可以使用默认的 ToStringSerializer 而不定义任何额外的类。但是你必须定义 toString() 方法只返回这个值。

    @JsonSerialize(using = ToStringSerializer.class)
    class ItemType
    {
       String name;
       int somethingElse;
       public String toString(){ return this.name;}
    }
    

    【讨论】:

      【解决方案5】:

      也许一种快速的解决方法是在Item 上添加一个额外的getter 以返回ItemType.name,并用@JsonIgnore 标记ItemType getter?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-14
        • 2014-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-11
        • 1970-01-01
        相关资源
        最近更新 更多