2016-07-18 133 views
3

要确保所发送的数据来回是不是在我的RESTful Web服务冗余,每一个嵌套的对象只有它的ID序列化(A MessageUser创造者不仅具有userId因为这两个序列客户端和服务器已经知道用户的所有细节)。JSON反序列化从ID为对象

序列化完美地工作,制造该:

{"messageCreatorUser":"60d01602-c04d-4a3f-bbf2-132eb0ebbfc6","messageBody":"Body", ...} 

问题:反序列化不产生嵌套对象仅具有其ID。生成的反序列化嵌套对象为null。

下面是前面提到的MessageUser对象。从此处指定的第三个选项使用序列化“策略”:How to serialize only the ID of a child with Jackson

Message.java

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "messageId") 
public class Message implements Serializable { 

    // -- Hibernate definitions omitted -- 
    private UUID messageId; 

    // ----------------------------------------------------------------- 
    // Here is what makes the serializer print out the ID specified on the class definition 

    @JsonIdentityReference(alwaysAsId = true) 

    // Here is my attempt to get the User class back when I deserialize 

    @JsonDeserialize(as = User.class) 
    @JsonSerialize(as = User.class) 

    private User messageCreatorUser; 
    // ------------------------------------------------------------------ 


    // -- more arbitrary properties -- 

    public Message() { 
    } 

    public Message(UUID messageId) { 
     this.messageId = messageId; 
    } 

    public Message(String messageId) { 
     this.messageId = UUID.fromString(messageId); 
    } 

    // -- getters and setters -- 

User.java

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "userId") 
@JsonInclude(JsonInclude.Include.NON_NULL) 
public class User implements Serializable { 

    private UUID userId; 

    // -- other arbitrary properties -- 

    public User() { 
    } 

    public User(UUID userId) { 
     this.userId = userId; 
    } 

    public User(String userId) { 
     this.userId = UUID.fromString(userId); 
    } 

    // -- getters and setters -- 

预期反序列化对象:

Message object = 
    String messageBody = "Body"; 
    User messageCreatorUser = 
     UUID userId = 60d01602-c04d-4a3f-bbf2-132eb0ebbfc6; 

实际反序列化对象:

  • Wildfly 10.0.Final:

    Message object = 
        String messageBody = "Body"; 
        User messageCreatorUser = null; 
    

    就像我说,我希望的嵌套User对象与的60d01602-c04d-4a3f-bbf2-132eb0ebbfc6

    仅使用ID来创建:

    • RESTEasy 3.0.15.Final
    • 的RESTEasy杰克逊2提供商3.0.15.Final
      • 杰克逊2.6.3(注释,核心,数据绑定等)

为什么结果不同?

回答

3

由于这里的答案(Jackson deserialize JsonIdentityReference (alwaysAsId = true))的状态,用二传手解串器效果很好,并不需要一个讨厌的定制解串器:

Message.java

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "messageId") 
public class Message implements Serializable { 

    private UUID messageId; 

    @JsonIdentityReference(alwaysAsId = true) 
    private User messageCreatorUser; 

    // -- other fields and such -- 

    public User getMessageCreatorUser() { 
     return messageCreatorUser; 
    } 

    public void setMessageCreatorUser(User messageCreatorUser) { 
     this.messageCreatorUser = messageCreatorUser; 
    } 

    @JsonProperty("messageCreatorUser") 
    public void setMessageCreatorUser(String userId) { 
     this.messageCreatorUser = new User(userId); 
    } 

User.java

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "userId") 
public class User implements Serializable { 

    private UUID userId; 

    // -- other fields -- 

    public User(String userId) { 
     this.userId = UUID.fromString(userId); 
    } 

} 

请注意,为了使用@JsonIdentityReference(alwaysAsId = true),你需要在某个地方有@JsonIdentityInfo(...)

2

不知道我理解的整个情况,但如果你只是想强制序列化作为一个id,你可以使用:

@JsonIdentityReference(alwaysAsId=true) 

牢记的是反序列化确实需要有一些方法来解决id返回到实例,通常意味着实际的完整对象应该通过其他属性引用进行序列化。

+0

我会澄清我使用的注释。我有'@JsonIdentityReference(alwaysAsId = true)'以及'@Json(De)Serialize(as = User.class)',希望它创建bean。 –

+0

强制序列化作为一个ID绝对要求所引用的对象在JSON内返回?也许我可以让序列化程序使用ID创建空的'User'对象并将其附加在一起? –

+0

它不是强制的,所以你绝对只能使用id,不需要占位符Object。但是,如果要读回数据,你必须能够以某种方式获取数据 - 这可能是好的,只是想提一下,因为它可能对某些用例有问题。 – StaxMan