使用 Jackson 进行非对称序列化和反序列化

Asymmetric serialization and deserialization using Jackson

我正在使用 Jackson 为 RESTful API 序列化和反序列化数据。我想要一个 REST 资源 (/comments),它允许 POST 评论以及获取评论列表。

这是发布到 /comments 的内容的(简化)示例。

{"text":"Text","author":"Paul","email":"paul@example.org"}

GET /comments 的结果应该是这样的:

[{"text":"Text","author":"Paul","emailHash":"76w0kjKP9HpsdhBjx895Sg=="}]

由于任何人都不应看到电子邮件地址,因此我决定 return 在响应中仅对电子邮件地址进行 MD5 哈希处理。

我创建了一个简单的 POJO class Comment,其中包含 textauthoremail 和 [=] 的 getter 和 setter 字段20=].

现在,当我序列化结果时,我得到的是:

[{"text":"Text","author":"Paul","email":null,"emailHash":"76w0kjKP9HpsdhBjx895Sg=="}]

但我真的不喜欢 email 在这里被 return 编辑为 null。它根本不应该包括在内。

在该字段上使用注释 @JsonIgnore 也会在反序列化时忽略它。我是否必须创建两个 classes,比如 CreationCommentResultComment 以及共享公共字段的超级 class Comment 还是有办法避免创建额外的 classes?

您可以将 @JsonIgnore 放在 getEmail 上以防止它被序列化为 JSON 并使用 @JsonCreator 向 Jackson 指示用于反序列化的构造函数。然后构造函数将只接受 email 属性 并将散列并分配给您的 emailHash 字段。

您可以在 Comment class 上放置一个 @JsonInclude 注释,以防止 null 字段也被序列化。

您的 class 最终可能看起来像这样:

@JsonInclude(Include.NON_NULL)
public class Comment {
    private final String email;
    private final String emailHash;

    @JsonCreator
    public Comment(@JsonProperty("email") String email) {
        this.email = email;
        this.emailHash = MD5.hash(email);
    }

    @JsonIgnore
    public String getEmail() {
        return email;
    }

    public String getEmailHash() {
        return emailHash;
    }
}

您根本不需要创建 2 类。使用 Jackson,您可以使用注释在序列化和反序列化期间完全控制 属性 的行为,使用 getter 中的 @JsonIgnore 可以防止 属性 在您的 Json 响应并在 setter 中使用 @JsonProperty 注释, 属性 将在反序列化期间设置。代码将如下所示:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Comment {

    private String author;

    private String email;

    @JsonIgnore
    public String getEmail() {
        return email;
    }

    @JsonProperty
    public void setEmail(String email) {
        this.email = email;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        Comment comment = new Comment();
        comment.setAuthor("anAuthor");
        comment.setEmail("email@example.com");

        try {
            System.out.println(objectMapper.writeValueAsString(comment));

            String json = "{\"author\":\"anAuthor\",\"email\":\"another@email.com\"}";
            Comment fromJson = objectMapper.readValue(json, Comment.class);

            System.out.println("Result from Json: author= " + fromJson.getAuthor() + ", email= " + fromJson.getEmail());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行main()方法测试解决方案后的输出:

{"author":"anAuthor"}

Result from Json: author= anAuthor, email= another@email.com

希望对您有所帮助,

何塞·路易斯