Jackson 是一个非常常见的库,用于在基于 Java 和 Spring Boot 的项目中处理 JSON 和序列化/反序列化。
Jackson 通过将它们原样映射到 JSON 来处理属性名称——所以
propertyName
在一个 POJO 中会有对应的propertyName
在 JSON 中。 将 JSON 转换为 POJO 时也遵循此约定,如果名称不匹配,则无法完成转换。
但是,在许多情况下,您希望序列化的 JSON 属性具有不同的名称,例如标准化其他服务的命名约定(使用类似 snake_case
, 代替 CamelCase
) 或冲突的属性名称 (a Customer
可以有一个 firstName
,就像一个 Agent
– 一份报告可能同时包含他们的 firstName
属性,需要序列化)。
让我们创建一个 Book
类,有几个简单的字段:
public class Book {
private String title;
private String author;
private int releaseYear;
public Book() {}
public Book(String title, String author, int releaseYear) {
this.title = title;
this.author = author;
this.releaseYear = releaseYear;
}
}
使用 Jackson 更改 JSON 字段名称
当通常转换一个实例时 Book
到 JSON 中,我们将对象的值写为 JSON 字符串,使用 ObjectMapper
:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
结果是:
{"title":"Our Mathematical Universe","author":"Max Tegmark","releaseYear":2014}
title
, author
和 releaseYear
是一对一的映射到 title
, author
和 releaseYear
POJO 的字段。 要更改 JSON 属性的名称并在序列化后保留它,无需更改您的 POJO! 用注释相关字段就足够了 @JsonProperty
,并提供 JSON 名称:
public class Book {
@JsonProperty("book_title")
private String title;
@JsonProperty("book_author")
private String author;
@JsonProperty("book_release_year")
private int releaseYear;
public Book(){}
public Book(String title, String author, int releaseYear) {
this.title = title;
this.author = author;
this.releaseYear = releaseYear;
}
}
现在,当我们实例化对象并将其转换为 JSON 时:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
代码导致:
{"book_title":"Our Mathematical Universe","book_author":"Max Tegmark","book_release_year":2014}
在 JSON 到 POJO 转换中更改 JSON 字段名称?
值得注意的是,更名并不是片面的。 相同的注释可以双向工作,并且可以将具有不同名称的传入 JSON 桥接到有效对象中。 例如,代表一本书的 JSON book_title
,不会映射到 title
的财产 Book
默认为类,因为它们不一样。
既然我们已经注释了 title
as book_title
- 转换工作得很好:
Book bookReconstructed = mapper.readValue(jsonBook, Book.class);
System.out.print(bookReconstructed);
结果是:
Book{title='Our Mathematical Universe', author='Max Tegmark', releaseYear=2014}
请注意: 要从 JSON 构造对象,您的类还需要有一个空的构造函数。 Jackson 首先实例化空对象,然后使用 getter 和 setter 填充字段。
使用 @JsonProperty 注释 Getter 和 Setter
您想为序列化和反序列化编码不同的名称吗? 例如,您可以序列化 Book
成一个 JSON bt
表示书名,但使用 JSON book_title
. 您可以自定义 getter 和 setter Book
上课 @JsonProperty
注释:
@JsonProperty("bt")
public String getBt() {
return title;
}
@JsonProperty("book_title")
public void setTitle(String title) {
this.title = title;
}
这样,在序列化时, getBt()
方法将序列化 title
作为一个 bt
JSON 中的字段。 从 JSON 读取(反序列化)时,您需要提供 book_title
, 被映射到 title
.
查看我们的 Git 学习实践指南,其中包含最佳实践、行业认可的标准以及随附的备忘单。 停止谷歌搜索 Git 命令,实际上 学习 它!
请注意: 以上皆是 bt
和 book_title
将被映射到 title
场,但这并不能使 bt
和 book_title
可互换。 如果没有先转换为,杰克逊将无法在它们之间转换 title
.
现在,您可以实例化一本书,将其序列化,然后将另一个字符串反序列化为一本书:
ObjectMapper mapper = new ObjectMapper();
Book book = new Book("Our Mathematical Universe", "Max Tegmark", 2014);
String jsonBook = mapper.writeValueAsString(book);
System.out.println(jsonBook);
String input = "{"author":"Max Tegmark","releaseYear":2017,"book_title":"Life 3.0"}";
Book bookReconstructed = mapper.readValue(input, Book.class);
System.out.print(bookReconstructed);
结果是:
{"author":"Max Tegmark","releaseYear":2014,"bt":"Our Mathematical Universe"}
Book{title='Life 3.0', author='Max Tegmark', releaseYear=2017}
结论
在这个简短的教程中,我们了解了 Jackson 如何将对象字段映射到 JSON,以及如何在序列化之前更改字段的名称。 我们还探索了使用不同的 JSON 名称进行序列化和反序列化的想法,使用 @JsonProperty
方法级别的注释,而不是字段级别的注释。