Jackson 是 Java 中的一个 Json 序列化工具,也是 SpringBoot 默认使用的 Json 序列化工具,这里梳理一下 jackson 的简单操作和一些配置事项。
Object <--> Json
jackson 提供一个非常简单并且常用的工具 ObjectMapper ,可以方便完成对象到 json (记为 write 操作)、json 到对象(记为 read):
// 序列化操作
ObjectMapper mapper = new ObjectMapper();
string json = mapper.writerValueAsString(object);
// 反序列化操作
Object object = mapper.readValue(json , Object.calss);Java常用注解
这些注解用于 JavaBean 的字段之上,用于规范格式等作用:
@JsonPerperty("new_name"): 序列化时 java 属性名和 Json 中的属性名不一致的场景,new_name 对应了 Json 中对应的名字。@JsonIgnore: 序列化时忽略该字段@JsonFormat:规范序列化的格式,用于 data 等类型。@jsonInclude(JsonInclude.Include.NON_NULL):如果为空值就直接不包含这个对象,可以减小生成 Json 的大小。
JsonNode
上面两个场景都是用来应该 JavaBean 与 Json 之间的转换。但是如果这是一个临时的 Json ,没必要为它再设置一个 JavaBean 呢。那么就可以使用 JsonNode ,然后以树型的方式进行操作:
String json = "{\"info\": {\"score\": 100}, \"tags\": [\"Java\", \"Redis\"]}";
JsonNode node = mapper.readTree(json);
// 链式获取数据
int score = node.get("info").get("score").asInt();
String firstTag = node.get("tags").get(0).asText();Java其他配置
时间序列化
jackson 中注册的类型大多是 Java8 之前的基本类型,所以他默认不支持 LocalDateTime 等时间类型的类,我们需要单独的进行注册:
ObjectMapper mapper = new ObjectMapper();
// 注册这个模块才能处理 Java 8 的时间类 (LocalDateTime, LocalDate 等)
mapper.registerModule(new JavaTimeModule());
// 禁用“将日期序列化为时间戳”。
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);Java容错配置
如果 Json 中的字段比 JavaBean 中少则没有任何问题,但是一旦 Json 中出现了 JavaBean 中不存在的字段, jackson 会立刻报错,我们可以通过配置的方式来跳过这些错误:
// 反序列化时:忽略在 JSON 中存在但 Java 类中不存在的字段
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 序列化时:如果是一个空对象(没有属性),不要报错
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);Java数据瘦身
上面提到的为 null 则不进行序列化的注解,也可以直接配置到 mapper 上:
// 仅包含非空字段。如果某个字段是 null,生成的 JSON 里将不包含这个 Key。
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);Javajackson 配置模版
@Configuration
public class JacksonConfig {
@Bean
@Primary
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule()) // 时间支持
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // 格式化时间
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) // 忽略未知字段
.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 字段
}
}Java
Comments NOTHING