You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从存储过程生成含数组的嵌套JSON并正确提取字段值(Java实现)

如何调整Java代码生成符合要求的嵌套JSON并正确提取字段?

我有一个由Stored Procedure生成的数据集:

LineStatusConsenttid
10011Yes1054
10021yes1055
10031Yes3045
10041No3046
10050No1023
10060Yes1024
10071No1025

我希望基于该数据集生成如下格式的嵌套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);
}

关键说明

  1. 泛型安全:将List指定为List<ListingModel>,循环时直接操作实体对象,无需强制类型转换,更安全清晰
  2. 正确提取字段:通过实体类的getter方法获取当前对象的对应字段值,而非操作整个集合
  3. 数据过滤:添加了status == 1和"yes".equalsIgnoreCase(model.getConsent())的条件,确保只收集符合预期的记录
  4. 避免无效操作:去掉了重复赋值questionaryinfo的无用代码
  5. 类型匹配:将数字类型的字段转换为字符串,完全匹配你期望的JSON格式

如果你的ListingModel还没有对应getter方法,需要先给实体类添加上getLine()、getStatus()、getConsent()、getTid()这些方法,才能正确提取字段值。


内容的提问来源于stack exchange,提问作者arriff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:32:51