
本文详解如何正确解析形如list
在实际Java开发中,尤其在处理REST API响应或配置化JSON数据时,常会遇到类似如下结构的字段:
"attributes": [
{ "id": "id", "value": "12345677890124566" },
{ "id": "Criticality", "value": "medium" },
{ "id": "type", "value": "business" },
{ "id": "active", "value": "true" }
]这类数据并非一个扁平的Map
✅ 正确解析逻辑应为:
- 将attributes字段解析为ArrayNode(Jackson中的JSON数组表示);
- 遍历每个JsonNode元素;
- 从每个元素中分别提取"id"和"value"字段值。
以下是完整、可运行的Jackson解析示例:
立即学习“Java免费学习笔记(深入)”;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
public class AttributeParser {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static void main(String[] args) throws Exception {
String json = "{ \"attributes\": [" +
"{\"id\":\"id\",\"value\":\"12345677890124566\"}," +
"{\"id\":\"Criticality\",\"value\":\"medium\"}," +
"{\"id\":\"type\",\"value\":\"business\"}," +
"{\"id\":\"active\",\"value\":\"true\"}" +
"]}";
JsonNode root = objectMapper.readTree(json);
ArrayNode attributes = (ArrayNode) root.get("attributes");
// 方式一:遍历并打印所有属性
attributes.forEach(node ->
System.out.printf("key='%s', value='%s'%n",
node.get("id").asText(),
node.get("value").asText())
);
// 方式二:转换为Map<String, String>便于后续使用(推荐)
Map<String, String> attributeMap = new HashMap<>();
attributes.forEach(node -> {
String id = node.get("id").asText();
String value = node.get("value").asText();
attributeMap.put(id, value);
});
// 使用示例
System.out.println("Active status: " + attributeMap.get("active")); // 输出: true
System.out.println("Type: " + attributeMap.get("type")); // 输出: business
}
}⚠️ 关键注意事项:
- ❌ 不要尝试将整个attributes数组强转为List
- ✅ 始终通过JsonNode层级访问:先取数组 → 再取每个对象 → 最后取"id"和"value";
- ? 若"value"可能为非字符串类型(如布尔、数字),请使用asBoolean()、asInt()等安全转换方法,避免asText()抛出异常;
- ?️ 生产环境建议封装为工具方法,并添加空值校验(如node.has("id") && node.has("value"));
- ? 依赖需引入:com.fasterxml.jackson.core:jackson-databind(Maven坐标)。
总结:理解JSON原始结构是正确解析的前提。面对[{"id":"k","value":"v"}]这类“伪Map”数组,应放弃“一步映射到Map”的幻想,采用面向JSON树的渐进式提取策略——既准确可靠,又具备良好的可维护性和扩展性。










