如何从存储过程生成含数组的嵌套JSON并正确提取字段值(Java实现)
如何调整Java代码生成符合要求的嵌套JSON并正确提取字段?
我有一个由Stored Procedure生成的数据集:
| Line | Status | Consent | tid |
|---|---|---|---|
| 1001 | 1 | Yes | 1054 |
| 1002 | 1 | yes | 1055 |
| 1003 | 1 | Yes | 3045 |
| 1004 | 1 | No | 3046 |
| 1005 | 0 | No | 1023 |
| 1006 | 0 | Yes | 1024 |
| 1007 | 1 | No | 1025 |
我希望基于该数据集生成如下格式的嵌套JSON:
{ "totalMembers": 9, "questionaryinfo": [ { "line": "1001", "status": "1", "consent": "Yes", "tid": "1054", "adultquestionary":"Yes" }, { "line": "1002", "status": "1", "consent": "Yes", "tid": "1055", "adultquestionary":"Yes" }, { "line": "1003", "status": "1", "consent": "Yes", "tid": "3035", "adultquestionary":"Yes" } ] }
我尝试使用HashMap实现,代码如下:
public ResponseEntity<Map<String, Object>> retrieveLineListing(String Case){ StoredProcedureQuery query = entityManager.createStoredProcedureQuery("get_listing", "ListingModel"); query.registerStoredProcedureParameter("Case", String.class, ParameterMode.IN); query.setParameter("Case", Case); query.execute(); List list = query.getResultList(); Map<String, Object> parent = new HashMap<>(); parent.put("totalMembers", 9); parent.put("questionaryinfo", new HashMap<String, Object>()); parent.put("questionaryinfo", new ArrayList<HashMap<String,Object>>()); ArrayList<HashMap<String,Object>> listings = (ArrayList<HashMap<String,Object>>) parent.get("questionaryinfo"); if (list != null) { list.forEach(d -> { HashMap<String,Object> entry = new HashMap<>(); entry.put("adultquestionary","Yes"); entry.put("consent", list.get(1)); listings.add(entry); }); } return ResponseEntity.ok().body(parent); }
UPDATE 1:按照@Rahul的建议修改后,生成的JSON格式如下:
{ "totalMembers": 9, "questionaryinfo": [ "consent"{ { "line": "1001", "status": "1", "consent": "Yes", "tid": "1054", }, "adultquestionary":"Yes" } "consent"{ { "line": "1002", "status": "1", "consent": "Yes", "tid": "1055", }, "adultquestionary":"Yes" }, "consent"{ { "line": "1003", "status": "1", "consent": "Yes", "tid": "3035", }, "adultquestionary":"Yes" }, ] }
请问如何调整我的方法,以生成符合要求的嵌套JSON,并正确提取Line、Status、consent和tid字段值?
问题分析
你的代码目前存在几个关键问题:
- 重复赋值
questionaryinfo:先把它设为HashMap又立刻覆盖成ArrayList,做了无用操作 - 字段提取错误:
list.get(1)是取整个集合的第二个元素,而非当前循环对象d里的consent字段 - 缺少其他字段映射:没有把
Line、Status、tid从实体对象中提取到entry里 - 未过滤目标数据:你期望的JSON只包含
Status=1且Consent为Yes/yes的记录,当前代码没做过滤
修正方案
假设你的ListingModel实体类已经包含line、status、consent、tid字段及对应getter方法,可以按下面的方式修改代码:
public ResponseEntity<Map<String, Object>> retrieveLineListing(String Case){ StoredProcedureQuery query = entityManager.createStoredProcedureQuery("get_listing", ListingModel.class); query.registerStoredProcedureParameter("Case", String.class, ParameterMode.IN); query.setParameter("Case", Case); query.execute(); // 指定泛型为ListingModel,避免强制类型转换 List<ListingModel> list = query.getResultList(); Map<String, Object> parent = new HashMap<>(); parent.put("totalMembers", 9); // 直接初始化ArrayList并放入parent,避免无效赋值 ArrayList<HashMap<String,Object>> listings = new ArrayList<>(); parent.put("questionaryinfo", listings); if (list != null && !list.isEmpty()) { list.forEach(model -> { // 过滤符合要求的记录:status为1,且consent不区分大小写为Yes if (model.getStatus() == 1 && "yes".equalsIgnoreCase(model.getConsent())) { HashMap<String,Object> entry = new HashMap<>(); // 从实体对象中提取各字段并转换为字符串类型 entry.put("line", String.valueOf(model.getLine())); entry.put("status", String.valueOf(model.getStatus())); entry.put("consent", model.getConsent()); entry.put("tid", String.valueOf(model.getTid())); entry.put("adultquestionary", "Yes"); listings.add(entry); } }); } return ResponseEntity.ok().body(parent); }
关键说明
- 泛型安全:将
List指定为List<ListingModel>,循环时直接操作实体对象,无需强制类型转换,更安全清晰 - 正确提取字段:通过实体类的getter方法获取当前对象的对应字段值,而非操作整个集合
- 数据过滤:添加了
status == 1和"yes".equalsIgnoreCase(model.getConsent())的条件,确保只收集符合预期的记录 - 避免无效操作:去掉了重复赋值
questionaryinfo的无用代码 - 类型匹配:将数字类型的字段转换为字符串,完全匹配你期望的JSON格式
如果你的ListingModel还没有对应getter方法,需要先给实体类添加上getLine()、getStatus()、getConsent()、getTid()这些方法,才能正确提取字段值。
内容的提问来源于stack exchange,提问作者arriff
相关产品推荐
相关产品推荐

