Jackson 反序列化Snake命名到Camel命名
Contents
1. 概述
JSON 对象中的字段名称可以采用多种格式。当我们想要将它们加载到 POJO 中时,我们可能会遇到 Java 代码中的属性名称与 JSON 中的命名约定不匹配的问题。
2. 安装Jackson
让我们首先将Jackson 依赖项 添加到我们的pom.xml文件中:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13</version>
</dependency>
3. 使用默认反序列化
让我们考虑一个示例User类:
public class User {
private String firstName;
private String lastName;
// standard getters and setters
}
让我们尝试加载此 JSON,它使用 Snake Case 命名标准(小写名称由*_*分隔):
{
"first_name": "Jackie",
"last_name": "Chan"
}
首先,我们需要使用ObjectMapper反序列化这个 JSON:
ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(JSON, User.class);
然而,当我们尝试这样做时,我们得到一个错误:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "first_name" (class com.blogdemo.jackson.snakecase.User), not marked as ignorable (2 known properties: "lastName", "firstName"])
不幸的是,Jackson 无法将 JSON 中的名称与User 中的字段名称完全匹配。 接下来,我们将学习三种方法来解决这个问题。
4. 使用*@JsonProperty*注解
我们可以在类的字段上使用*@JsonProperty*注解将字段映射到 JSON 中的确切名称:
public class UserWithPropertyNames {
@JsonProperty("first_name")
private String firstName;
@JsonProperty("last_name")
private String lastName;
// standard getters and setters
}
现在我们可以将 JSON 反序列化为UserWithPropertyNames:
ObjectMapper objectMapper = new ObjectMapper();
UserWithPropertyNames user = objectMapper.readValue(JSON, UserWithPropertyNames.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());
5. 使用*@JsonNaming*注解
接下来,我们可以在类上使用*@JsonNaming注解,*所有字段将使用 snake case 反序列化:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class UserWithSnakeStrategy {
private String firstName;
private String lastName;
// standard getters and setters
}
然后再次反序列化我们的 JSON:
ObjectMapper objectMapper = new ObjectMapper();
UserWithSnakeStrategy user = objectMapper.readValue(JSON, UserWithSnakeStrategy.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());
6. 配置ObjectMapper
最后,我们可以使用ObjectMapper上的setPropertyNamingStrategy方法为所有序列化配置它:
ObjectMapper objectMapper = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
User user = objectMapper.readValue(JSON, User.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());
如我们所见,我们现在可以将 JSON 反序列化为原始User对象,即使User类没有任何注解。
我们应该注意到还有其他命名约定(例如 kebab 大小写),并且上述解决方案也适用于它们。