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

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

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

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

以下是GET /comments的结果:

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

由于任何人都不应该看到电子邮件地址,因此我决定只返回响应中电子邮件地址的MD5哈希值。

我创建了一个简单的POJO类Comment ,其中包含用于textauthoremailemail emailHash getter和setter的字段。

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

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

但我真的不喜欢email在这里返回null 。 它根本不应该被包括在内。

在该字段上使用注释@JsonIgnore也将在反序列化时忽略它。 我是否必须创建两个类,例如CreationCommentResultComment以及一个共享公共字段的超类Comment ,或者是否有一种方法可以避免创建其他类?

您根本不必创建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

希望能帮助到你,

何塞路易斯

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

您可以在Comment类上放置@JsonInclude批注,以防止null字段的序列化。

你的课可能最终看起来像这样:

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