使用json-simple解析嵌套JSON时遇类型转换与空值问题求助
问题分析与解决方案
首先,你的代码存在几个关键错误导致解析失败:
characterizations_values是JSON数组(而非Map),直接强转为Map<String,String>会导致类型不匹配- 错误地创建新JSONObject来包装sheet,而非直接从原数据中提取已存在的sheet对象
- 未逐层处理嵌套的数组和对象结构
以下是修正后的解析方案,严格按照你提出的逐层解析顺序实现:
修正后的代码
import org.json.simple.JSONObject; import org.json.simple.JSONArray; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import java.io.FileReader; import java.io.IOException; public class JsonParserFix { public static void main(String[] args) { JSONParser parser = new JSONParser(); try (FileReader reader = new FileReader("your-json-file-path.json")) { // 解析根JSON对象 JSONObject rootObj = (JSONObject) parser.parse(reader); // 1. 获取characterizations_values数组(注意是数组类型) JSONArray charValuesArray = (JSONArray) rootObj.get("characterizations_values"); JSONObject charValueItem = (JSONObject) charValuesArray.get(0); // 2. 提取sheet对象 JSONObject sheetObj = (JSONObject) charValueItem.get("sheet"); // 3. 解析my-title部分 JSONArray myTitleArray = (JSONArray) sheetObj.get("my-title"); JSONObject titleContent = (JSONObject) myTitleArray.get(0); // 获取title内的字段 String number = (String) titleContent.get("number"); String numberedPart = (String) titleContent.get("numbered-part"); // 解析嵌套的documents数组 JSONArray docsOuterArr = (JSONArray) titleContent.get("documents"); JSONArray docsInnerArr = (JSONArray) docsOuterArr.get(0); JSONObject docObj = (JSONObject) docsInnerArr.get(0); String docName = (String) docObj.get("document_name"); JSONArray docCategories = (JSONArray) docObj.get("document-category"); // 4. 解析my-notes部分 JSONArray myNotesArray = (JSONArray) sheetObj.get("my-notes"); JSONObject notesContent = (JSONObject) myNotesArray.get(0); JSONObject dimensions = (JSONObject) notesContent.get("dimensions"); JSONObject enclosing = (JSONObject) dimensions.get("enclosing"); double testOneEnclosing = (double) enclosing.get("test-one"); long testTwoEnclosing = (long) enclosing.get("test-two"); JSONObject enclosingExtra = (JSONObject) dimensions.get("enclosing-extra"); double testOneExtra = (double) enclosingExtra.get("test-one"); long testTwoExtra = (long) enclosingExtra.get("test-two"); // 测试输出 System.out.println("Number: " + number); System.out.println("Document Name: " + docName); System.out.println("Test One Enclosing: " + testOneEnclosing); } catch (IOException | ParseException e) { e.printStackTrace(); } } }
关键注意事项
- 严格匹配类型:JSON中
[]对应JSONArray,{}对应JSONObject,必须准确强制类型转换 - 逐层提取:从根对象开始向下逐层获取,不要跨层级操作
- 数组元素处理:即使数组只有一个元素,也要先获取数组再取第一个元素(比如
characterizations_values和my-title) - 数值类型区分:json-simple会将整数解析为
Long,浮点数解析为Double,避免错误转换
替代方案建议
如果觉得json-simple的手动类型转换过于繁琐,可以改用Jackson或Gson库,它们支持将JSON直接映射到Java实体类,省去逐层解析的麻烦:
以Gson为例:
- 创建对应JSON结构的实体类:
public class CharacterizationsValue { private String filename; private Sheet sheet; // getter/setter } public class Sheet { @SerializedName("my-title") private List<MyTitle> myTitle; @SerializedName("my-notes") private List<MyNote> myNotes; // getter/setter } // 其他嵌套实体类(MyTitle、MyNote等)省略...
- 解析代码:
Gson gson = new Gson(); String jsonString = // 读取JSON文件内容 CharacterizationsValue[] values = gson.fromJson(jsonString, CharacterizationsValue[].class);
内容的提问来源于stack exchange,提问作者spoons
相关产品推荐
相关产品推荐

