Java JSON 最佳实践
JSON (JavaScript Object Notation) 已经成为现代应用程序中数据交换的标准格式。在 Java 开发中,正确高效地处理 JSON 数据对于开发健壮的应用程序至关重要。本文将介绍 Java 处理 JSON 的最佳实践,帮助你避免常见陷阱并提高代码质量。
JSON 库的选择
在 Java 中,有多种处理 JSON 的库可供选择:
- Jackson - 功能全面,性能优秀,是目前最流行的选择
- Gson - 由 Google 开发,API 简洁易用
- JSON-B (javax.json.bind) - Java EE 的标准 JSON 绑定 API
- org.json - 轻量级但功能有限的库
提示
对于大多数项目,Jackson 是推荐选择,因为它结合了高性能、丰富功能和良好的社区支持。
添加 Jackson 依赖
在 Maven 项目中添加 Jackson 依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
在 Gradle 项目中:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
基本序列化与反序列化最佳实践
1. 使用对象映射器的单例实例
ObjectMapper
是线程安全的,创建它的实例开销较大,因此应该重用:
// 好的做法
public class JsonUtils {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public static String toJson(Object obj) throws JsonProcessingException {
return OBJECT_MAPPER.writeValueAsString(obj);
}
public static <T> T fromJson(String json, Class<T> clazz) throws JsonProcessingException {
return OBJECT_MAPPER.readValue(json, clazz);
}
}
2. 正确处理异常
不要吞掉异常,而应该适当处理它们:
try {
User user = objectMapper.readValue(jsonString, User.class);
// 处理用户对象
} catch (JsonParseException e) {
log.error("JSON 格式错误: {}", e.getMessage());
} catch (JsonMappingException e) {
log.error("JSON 映射到对象失败: {}", e.getMessage());
} catch (IOException e) {
log.error("读取 JSON 时 IO 异常: {}", e.getMessage());
}
3. 使用正确的类型引用处理泛型
当处理泛型类型时,使用 TypeReference
:
String json = "[{\"name\":\"张三\",\"age\":25}, {\"name\":\"李四\",\"age\":30}]";
List<User> users = objectMapper.readValue(json, new TypeReference<List<User>>() {});
高级配置最佳实践
1. 配置 ObjectMapper
根据项目需求正确配置 ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper()
// 序列化时包含空字段
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
// 未知属性不抛出异常
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// 允许单引号
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
// 允许没有引号的字段名
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
// 日期格式化
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
2. 使用注解自定义 JSON 行为
public class User {
private String id;
@JsonProperty("full_name") // 指定 JSON 属性名称
private String name;
@JsonFormat(pattern = "yyyy-MM-dd") // 格式化日期
private Date birthDate;
@JsonIgnore // 在序列化时忽略此字段
private String password;
// getters and setters
}
3. 处理复杂对象层次结构
使用 @JsonTypeInfo
和 @JsonSubTypes
处理多态:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
private String name;
// getters and setters
}
public class Dog extends Animal {
private String breed;
// getters and setters
}
public class Cat extends Animal {
private boolean isIndoor;
// getters and setters
}