从ID到对象的{JSON反序列化

时间:2016-07-18 17:50:01

标签: jackson

为了确保在我的RESTful Web服务中来回发送的数据不是多余的,每个嵌套对象只有序列化的ID(A Message的{​​{1}}创建者只有{{ 1}}序列化,因为客户端和服务器都已经知道用户的所有细节。

序列化工作完美,产生了这个:

User

问题:反序列化不会生成仅包含其ID的嵌套对象。生成的反序列化嵌套对象为null。

以下是前面提到的userId{"messageCreatorUser":"60d01602-c04d-4a3f-bbf2-132eb0ebbfc6","messageBody":"Body", ...} 个对象。序列化“策略”使用了此处指定的第3个选项:How to serialize only the ID of a child with Jackson

Message.java

Message

User.java

User

预期的反序列化对象:

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

实际反序列化对象:

@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; ID

的嵌套Message object = String messageBody = "Body"; User messageCreatorUser = null; 对象

使用:

  • Wildfly 10.0.Final:
    • RESTEasy 3.0.15.Final
    • RESTEasy Jackson 2 Provider 3.0.15.Final
      • Jackson 2.6.3 (注释,核心,数据绑定等)

为什么结果不同?

2 个答案:

答案 0 :(得分:4)

正如这里的答案(Jackson deserialize JsonIdentityReference (alwaysAsId = true))所述,使用setter反序列化器效果很好,并且不需要讨厌的自定义反序列化器:

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(...)

答案 1 :(得分:2)

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

 @JsonIdentityReference(alwaysAsId=true)

请记住,反序列化确实需要某种方法将该ID解析回实例,这通常意味着实际的完整Object应该通过其他属性引用进行序列化。