1. 概述
JSON(JavaScript Object Notation)是一种轻量级、结构化的数据交换格式。现代软件广泛使用JSON进行数据交换、配置管理和API通信。在Java中处理JSON通常依赖org.json、Jackson或Gson等库。虽然将JSON对象转换为JSON数组看似简单,但正确的实现方式取决于输入结构和期望的输出格式。
本文将通过代码示例和JUnit测试,演示如何使用不同库实现JSON对象到JSON数组的转换。
2. 使用场景与注意事项
在REST API交互、数据管道或配置文件处理的应用中,JSON对象转JSON数组是常见需求。当原本建模为键值对的数据需要序列化、迭代或重新格式化时(例如前端框架要求接收对象数组而非Map),这种转换就变得必要。
选择转换方法前,开发者需明确:
- ✅ 是否只需要JSON对象中的值
- ✅ 是否需要同时保留键和值作为独立实体
- ⚠️ 转换后的JSON数组用途(展示/传输/后续处理),这直接影响库选择和转换策略
3. 转换实现方案
下面介绍三种将JSON对象转换为JSON数组的方法。每种方案都会先封装核心逻辑,再通过JUnit验证正确性。
3.1. 使用org.json库
org.json库简单易用,已集成到许多Java项目中。它为JSONObject
和JSONArray
提供了直观的API。我们实现两种常见场景:
场景1:仅提取值
JSONArray convertValuesToArray(JSONObject jsonObject) {
return new JSONArray(jsonObject.toMap().values());
}
此方法提取values()
集合并包装为JSONArray
,生成仅包含值的数组。
验证测试:
@Test
void givenFlatJSONObject_whenConvertValues_thenJSONArrayOfValues() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", 1);
jsonObject.put("name", "Alice");
OrgJsonConverter converter = new OrgJsonConverter();
JSONArray result = converter.convertValuesToArray(jsonObject);
assertEquals(2, result.length());
assertTrue(result.toList().contains("Alice"));
}
场景2:键值对转对象数组
JSONArray convertToEntryArray(JSONObject jsonObject) {
JSONArray result = new JSONArray();
for (String key : jsonObject.keySet()) {
JSONObject entry = new JSONObject();
entry.put("key", key);
entry.put("value", jsonObject.get(key));
result.put(entry);
}
return result;
}
遍历JSONObject
的每个键,创建包含key
和value
字段的新对象。
验证测试:
@Test
void givenFlatJSONObject_whenConvertToEntryArray_thenJSONArrayOfObjects() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("language", "Java");
jsonObject.put("framework", "Spring");
OrgJsonConverter converter = new OrgJsonConverter();
JSONArray result = converter.convertToEntryArray(jsonObject);
assertEquals(2, result.length());
assertEquals("language", result.getJSONObject(0).get("key"));
}
3.2. 使用Jackson自定义逻辑
Jackson是功能强大的JSON处理库。虽然主要使用树模型,但通过内部转换仍可处理JSONObject
:
ArrayNode convertToArray(JSONObject jsonObject) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.convertValue(jsonObject.toMap(), JsonNode.class);
ArrayNode result = mapper.createArrayNode();
jsonNode.fields().forEachRemaining(entry -> {
ObjectNode obj = mapper.createObjectNode();
obj.put("key", entry.getKey());
obj.set("value", entry.getValue());
result.add(obj);
});
return result;
}
先将JSONObject
转为Map,再用Jackson的convertValue()
处理为JsonNode
,最终构建包含键值对象的ArrayNode
。
验证测试:
@Test
void givenJSONObject_whenConvertToArray_thenArrayNodeOfKeyValueObjects() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("country", "India");
jsonObject.put("code", "IN");
JacksonConverter converter = new JacksonConverter();
ArrayNode result = converter.convertToArray(jsonObject);
assertEquals(2, result.size());
assertEquals("country", result.get(0).get("key").asText());
}
3.3. 使用Gson处理JSON对象
Gson虽不直接支持JSONObject
,但可通过内部Map转换实现:
JsonArray convertToKeyValueArray(JSONObject jsonObject) {
JsonArray result = new JsonArray();
jsonObject.keySet().forEach(key -> {
JsonObject entry = new JsonObject();
entry.addProperty("key", key);
entry.add("value", com.google.gson.JsonParser.parseString(jsonObject.get(key).toString()));
result.add(entry);
});
return result;
}
遍历键集合,为每个键值对创建包含key
和value
字段的新对象。
验证测试:
@Test
void givenJSONObject_whenConvertToKeyValueArray_thenJsonArrayWithObjects() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("brand", "Tesla");
jsonObject.put("year", 2024);
GsonConverter converter = new GsonConverter();
JsonArray result = converter.convertToKeyValueArray(jsonObject);
assertEquals(2, result.size());
assertEquals("brand", result.get(0).getAsJsonObject().get("key").getAsString());
}
4. 总结
本文探讨了使用主流Java JSON库实现对象转数组的三种方案:
- ✅ org.json:简洁直接,支持值提取和键值对转换
- ✅ Jackson:适合复杂数据模型和Jackson生态集成
- ✅ Gson:轻量级方案,适合Android或微服务环境
选择时需考虑:
- 项目现有技术栈
- 转换数据的复杂度
- 性能要求(Jackson通常性能最优)
⚠️ 踩坑提示:处理嵌套对象时需递归转换,以上示例仅展示扁平结构。完整代码见GitHub仓库。