使用 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
,其中包含 text
、author
、email
和 [=] 的 getter 和 setter 字段20=].
现在,当我序列化结果时,我得到的是:
[{"text":"Text","author":"Paul","email":null,"emailHash":"76w0kjKP9HpsdhBjx895Sg=="}]
但我真的不喜欢 email
在这里被 return 编辑为 null
。它根本不应该包括在内。
在该字段上使用注释 @JsonIgnore
也会在反序列化时忽略它。我是否必须创建两个 classes,比如 CreationComment
和 ResultComment
以及共享公共字段的超级 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
希望对您有所帮助,
何塞·路易斯
我正在使用 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
,其中包含 text
、author
、email
和 [=] 的 getter 和 setter 字段20=].
现在,当我序列化结果时,我得到的是:
[{"text":"Text","author":"Paul","email":null,"emailHash":"76w0kjKP9HpsdhBjx895Sg=="}]
但我真的不喜欢 email
在这里被 return 编辑为 null
。它根本不应该包括在内。
在该字段上使用注释 @JsonIgnore
也会在反序列化时忽略它。我是否必须创建两个 classes,比如 CreationComment
和 ResultComment
以及共享公共字段的超级 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
希望对您有所帮助,
何塞·路易斯