杰克逊:JsonTypeInfo不添加属性

时间:2013-07-05 11:40:39

标签: json spring-mvc jpa polymorphism jackson

我正在尝试使用Jackson来序列化具有多态性的实体。序列化的JSON字符串应该包含一个额外的“type”属性,其中“groupA”或“groupB”作为值,但它不是。 我的实体看起来像这样:

@Entity
@Table(name = "\"group\"")
@Inheritance(strategy = InheritanceType.JOINED)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = GroupA.class, name = "groupA"),
    @JsonSubTypes.Type(value = GroupB.class, name = "groupB")
})
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class Group implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    // ...
}



@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class GroupA extends Group {
    //...
}



@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class GroupB extends Group {
    // ...
}

您知道为什么序列化程序不添加类型属性吗?

3 个答案:

答案 0 :(得分:8)

问题是控制器操作:

@RequestMapping(...)
@ResponseBody
public Map<String, Object> getGroups() {
    Map<String, Object> response = new HashMap<String, Object>();
    List<Group> groups = magicallyRetrieveGroupsFromNarnia();
    response.put("groups", groups);
    response.put("status", Status.OK);
    return response;
}

它返回String-Object元组的映射。 MappingJackson2HttpMessageConverter将此映射抛出到ObjectMapper中。 ObjectMapper并不关心提供的地图内容的@JsonTypeInfo,因为它不知道它。所有它看到的都是类型擦除的List实例,令人不舒服的Object-suit。

有多种方法可以解决此问题:

  • 使用地图&gt;。
    • 缺点:您不能混合类型(整数,字符串,复杂对象,列表......)。
    • 优点:非常简单。
  • 创建一个显式的GroupList。
    • 缺点:杂乱。
    • 优势:适用于地图。
  • 使用显式字段创建复杂对象。
    • 缺点:杂乱。
    • 优势:适用于地图。
  • 在自定义MappingJackson2HttpMessageConverter扩展中使用类型编写器。
    • 缺点:相当复杂。
    • 优势:地狱般灵活。

这个JIRA问题帮助我理解了这个问题: https://github.com/FasterXML/jackson-databind/issues/364

答案 1 :(得分:1)

您可能需要在此指定EXTERNAL_PROPERTY,因为相关类没有“type”属性。

答案 2 :(得分:0)

也许你的Group类需要一个字段“type”?像这样: private String type;使用getter和setter,当然