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

含嵌套数组的JSON解析求助(附Java生成代码与JSON示例)

解决嵌套数组JSON的解析难题

我来帮你搞定这个JSON解析的麻烦事儿!先梳理下你的情况:你用Java从数据库生成了一段带嵌套结构的JSON,但解析的时候碰了不少钉子。先拆解问题根源,再给你针对性的解决方案。

待解析的JSON内容

[ { }, { "Cliente0":[ { "codrefcli":"1541121" }, { "razonsocial":"Perico de los palotes" }, { "cif":"45417265" }, { "num":"964491837" }, { "correo":"perico@yahoo.com" }, { "direccion":"calle maria la vieja" }, { "metodopago":"T" }, { "observaciones":"que pesado" } ] }, { "Empleado0":[ { "codempleado":"1" }, { "nombre":"Carlos" }, { "apellidos":"Basilio" }, { "dni":"15421451H" }, { "direccion":"Calle el rio" }, { "fechaalta":"2018-05-17" }, { "copiacontrato":"aaa" }, { "numcuenta":"884723877" } ] }, { }, { "PedidoCliente0":[ { "numped":"454524" }, { "fechapedido":"2018-05-09" }, { "formapago":"Efectivo" }, { "enviadoa":"Perico de los palotes" }, { "codcliente":"1541121" }, { "cpp":"5132413" } ] }, { "PedidoProveedor0":[ { "numped":"7455112" }, { "fechapedido":"2018-05-01" }, { "formapago":"Efectivo" }, { "enviadoa":"Calle el marino" }, { "codcliente":"10" }, { "cpp":"4555424" } ] }, { "Producto0":[ { "crf":"4555424" }, { "name":"Limpiador" }, { "desc":"Producto de importacion italiano" }, { "pve":"8.44" }, { "pvp":"14.99" }, { "cdp":"10" }, { "familia":"Limpieza" }, { "existencias":"10" } ], "Producto1":[ { "crf":"5132413" }, { "name":"Colador" }, { "desc":"Colador de acero" }, { "pve":"15" }, { "pvp":"18" }, { "cdp":"10" }, { "familia":"Cocina" }, { "existencias":"100" } ] }, { }, { "Proveedor0":[ { "crf":"10" }, { "razonsocial":"pene" }, { "cif":"10" }, { "num":"10" }, { "correo":"10" }, { "direccion":"10" }, { "metodopago":"1" }, { "observaciones":"10" } ], "Proveedor1":[ { "crf":"5421452" }, { "razonsocial":"Falete" }, { "cif":"45411" }, { "num":"42314" }, { "correo":"falete@gmail.com" }, { "direccion":"tu casa" }, { "metodopago":"T" }, { "observaciones":"Es muy pesado" } ] } ]

问题根源分析

你的Java生成代码犯了一个典型的小错误:把同一个实体的每个字段单独封装成一个JSONObject,再塞进数组里。比如一个客户的codrefcli、razonsocial等字段,本该放在同一个对象里,但你却给每个字段新建一个对象,导致生成的JSON里每个客户都是一个数组,数组里全是只有单个键值对的小对象。这种结构不仅冗余,解析起来也格外麻烦。

举个例子,你原来的Clientes部分代码:

while(rs.next()) {
    JSONArray list2 = new JSONArray();
    JSONObject jobja = new JSONObject();
    JSONObject jobjb = new JSONObject();
    // ... 每个字段都new一个JSONObject
    jobja.put("codrefcli", b1);
    jobjb.put("razonsocial", b2);
    // ... 把所有单字段对象加到数组
    list2.add(jobja);
    list2.add(jobjb);
    // ...
    jobjt2.put("Cliente"+i++, list2);
}

这就导致了Cliente0是一个数组,里面全是单键对象,完全没必要。

改进的Java生成代码

正确的做法是:把同一个实体的所有字段都放到一个JSONObject里,如果是多个实体,就统一放到JSONArray中。比如修改后的Clientes部分代码:

// Clientes
String query2 = "select * from Clientes";
rs = st.executeQuery(query2);
JSONArray clientesArray = new JSONArray(); // 用数组存所有客户
i=0;
while(rs.next()) {
    JSONObject clienteObj = new JSONObject(); // 一个客户对应一个对象
    String b1 = rs.getString("CodRefCli");
    String b2 = rs.getString("RazonSocial");
    String b3 = rs.getString("CIF");
    String b4 = rs.getString("Num");
    String b5 = rs.getString("Correo");
    String b6 = rs.getString("Direccion");
    String b7 = rs.getString("MetodoPago");
    String b8 = rs.getString("Observaciones");
    
    // 所有字段都放到同一个对象里
    clienteObj.put("codrefcli", b1);
    clienteObj.put("razonsocial", b2);
    clienteObj.put("cif", b3);
    clienteObj.put("num", b4);
    clienteObj.put("correo", b5);
    clienteObj.put("direccion", b6);
    clienteObj.put("metodopago", b7);
    clienteObj.put("observaciones", b8);
    
    clientesArray.add(clienteObj); // 把客户对象加到数组
    // 如果还是要保留原来的命名方式(比如Cliente0、Cliente1),可以替换成:
    // jobjt2.put("Cliente"+i++, clienteObj);
}
listt.add(clientesArray); // 或者add(jobjt2),根据你需要的结构选择

其他部分(Empleados、Productos等)都可以按照这个逻辑修改,生成的JSON结构会清晰很多,比如Clientes部分会变成:

[
  {
    "codrefcli":"1541121",
    "razonsocial":"Perico de los palotes",
    "cif":"45417265",
    ...
  }
]

或者如果你保留Cliente0这样的键,就是:

{
  "Cliente0": {
    "codrefcli":"1541121",
    "razonsocial":"Perico de los palotes",
    ...
  },
  "Cliente1": { ... }
}

解析JSON的示例代码

情况1:解析改进后的清晰结构(以Clientes数组为例)

用org.json库解析,代码非常直观:

import org.json.JSONArray;
import org.json.JSONObject;

public class JsonParser {
    public static void main(String[] args) {
        String jsonStr = "你的改进后的JSON字符串";
        JSONArray mainArray = new JSONArray(jsonStr);
        
        // 假设Clientes是mainArray里的第二个元素(索引1)
        JSONArray clientesArray = mainArray.getJSONArray(1);
        for (int j = 0; j < clientesArray.length(); j++) {
            JSONObject cliente = clientesArray.getJSONObject(j);
            String codrefcli = cliente.getString("codrefcli");
            String razonsocial = cliente.getString("razonsocial");
            String cif = cliente.getString("cif");
            // ... 获取其他字段
            System.out.println("客户:" + razonsocial + ",编码:" + codrefcli);
        }
    }
}

情况2:解析你原来的冗余结构(不推荐,但可以实现)

如果你暂时不想修改生成代码,也可以解析原来的JSON,只是需要遍历数组里的每个单键对象,把它们合并成一个完整的实体:

import org.json.JSONArray;
import org.json.JSONObject;

public class OldJsonParser {
    public static void main(String[] args) {
        String jsonStr = "你原来的JSON字符串";
        JSONArray mainArray = new JSONArray(jsonStr);
        
        // 获取Cliente0所在的对象(mainArray的索引1)
        JSONObject clienteWrapper = mainArray.getJSONObject(1);
        JSONArray clienteFieldsArray = clienteWrapper.getJSONArray("Cliente0");
        
        // 合并成一个完整的客户对象
        JSONObject cliente = new JSONObject();
        for (int j = 0; j < clienteFieldsArray.length(); j++) {
            JSONObject fieldObj = clienteFieldsArray.getJSONObject(j);
            // 每个fieldObj只有一个键值对,遍历取出键
            String key = fieldObj.keys().next();
            Object value = fieldObj.get(key);
            cliente.put(key, value);
        }
        
        // 现在可以正常获取字段了
        System.out.println("客户名称:" + cliente.getString("razonsocial"));
        System.out.println("客户编码:" + cliente.getString("codrefcli"));
    }
}

总结

优先推荐改进Java生成代码,生成结构清晰的JSON,这样解析会非常简单,也符合JSON的最佳实践。如果必须解析原来的冗余结构,就用第二种方法合并字段对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:21