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

Java中ScuolaEntity列表转嵌套JSON并深度处理的实现问询

如何将ScuolaEntity列表转换为指定结构的JSON?

我持有一个ScuolaEntity类型的对象列表:

List<ScuolaEntity> result = scuolaService.getAllScuoleEntity();

需要将该列表转换为JSON对象并进行深度结构调整,试过Gson、JSONObject以及JsonNode,但没找到合适的深度处理方法。

当前生成的JSON结构

[
    {
        "codiceMeccanografico": "RMAT123456",
        "anno": 2022,
        "sezione": "A",
        "nome": "PIETRO",
        "cognome": "BUCCIANTI",
        "classe": {
            "anno": 2022,
            "sezione": "A"
        }
    },
    {
        "codiceMeccanografico": "RMAT123456",
        "anno": 2022,
        "sezione": "A",
        "nome": "LEONARDO",
        "cognome": "FANTE",
        "classe": {
            "anno": 2022,
            "sezione": "A",
            "ubicazione": "PIANO TERRA"
        }
    }
]

期望的目标JSON结构

{
  "scuola": {
    "codiceMeccanografico": "RMAT123456",
    "classe": {
      "anno": 2022,
      "sezione": "A",
      "studenti": [
        {
          "nome": "PIETRO",
          "cognome": "BUCCIANTI"
        },
        {
          "nome": "LEONARDO",
          "cognome": "FANTE"
        }
      ]
    }
  }
}

解决方案

直接操作JSON节点容易出错,更清晰的方式是定义与目标JSON结构匹配的DTO类,然后通过Java Stream分组转换数据,最后用Gson序列化。

1. 定义DTO类

// 学生数据传输对象
class StudenteDTO {
    private String nome;
    private String cognome;

    public StudenteDTO(String nome, String cognome) {
        this.nome = nome;
        this.cognome = cognome;
    }

    // IDE自动生成getter、setter
    public String getNome() { return nome; }
    public void setNome(String nome) { this.nome = nome; }
    public String getCognome() { return cognome; }
    public void setCognome(String cognome) { this.cognome = cognome; }
}

// 班级数据传输对象
class ClasseDTO {
    private Integer anno;
    private String sezione;
    private String ubicazione;
    private List<StudenteDTO> studenti;

    // IDE自动生成getter、setter
    public Integer getAnno() { return anno; }
    public void setAnno(Integer anno) { this.anno = anno; }
    public String getSezione() { return sezione; }
    public void setSezione(String sezione) { this.sezione = sezione; }
    public String getUbicazione() { return ubicazione; }
    public void setUbicazione(String ubicazione) { this.ubicazione = ubicazione; }
    public List<StudenteDTO> getStudenti() { return studenti; }
    public void setStudenti(List<StudenteDTO> studenti) { this.studenti = studenti; }
}

// 学校数据传输对象
class ScuolaDTO {
    private String codiceMeccanografico;
    private ClasseDTO classe;

    // IDE自动生成getter、setter
    public String getCodiceMeccanografico() { return codiceMeccanografico; }
    public void setCodiceMeccanografico(String codiceMeccanografico) { this.codiceMeccanografico = codiceMeccanografico; }
    public ClasseDTO getClasse() { return classe; }
    public void setClasse(ClasseDTO classe) { this.classe = classe; }
}

// 顶层响应对象
class ResponseDTO {
    private ScuolaDTO scuola;

    // IDE自动生成getter、setter
    public ScuolaDTO getScuola() { return scuola; }
    public void setScuola(ScuolaDTO scuola) { this.scuola = scuola; }
}

2. 数据转换与序列化

// 按学校编码、班级(年+班号)分组
Map<String, Map<String, List<ScuolaEntity>>> groupedData = result.stream()
    .collect(Collectors.groupingBy(
        ScuolaEntity::getCodiceMeccanografico,
        Collectors.groupingBy(entity -> entity.getAnno() + "-" + entity.getSezione())
    ));

ResponseDTO response = new ResponseDTO();

// 处理分组后的数据(示例假设只有一个学校和一个班级,多组可循环处理)
if (!groupedData.isEmpty()) {
    // 取出第一个学校的分组
    Map.Entry<String, Map<String, List<ScuolaEntity>>> schoolEntry = groupedData.entrySet().iterator().next();
    String schoolCode = schoolEntry.getKey();

    // 取出该学校下第一个班级的分组
    Map.Entry<String, List<ScuolaEntity>> classEntry = schoolEntry.getValue().entrySet().iterator().next();
    List<ScuolaEntity> studentEntities = classEntry.getValue();

    // 构建班级DTO
    ClasseDTO classeDTO = new ClasseDTO();
    ScuolaEntity firstEntity = studentEntities.get(0);
    classeDTO.setAnno(firstEntity.getAnno());
    classeDTO.setSezione(firstEntity.getSezione());
    
    // 提取班级的ubicazione(取第一个有值的记录)
    classeDTO.setUbicazione(studentEntities.stream()
        .map(ScuolaEntity::getClasse)
        .filter(classe -> classe.getUbicazione() != null && !classe.getUbicazione().isEmpty())
        .findFirst()
        .map(classe -> classe.getUbicazione())
        .orElse(null));

    // 转换学生列表为StudenteDTO
    List<StudenteDTO> studentDTOs = studentEntities.stream()
        .map(entity -> new StudenteDTO(entity.getNome(), entity.getCognome()))
        .collect(Collectors.toList());
    classeDTO.setStudenti(studentDTOs);

    // 构建学校DTO
    ScuolaDTO scuolaDTO = new ScuolaDTO();
    scuolaDTO.setCodiceMeccanografico(schoolCode);
    scuolaDTO.setClasse(classeDTO);

    response.setScuola(scuolaDTO);
}

// 用Gson序列化为格式化后的JSON
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String targetJson = gson.toJson(response);
System.out.println(targetJson);

说明

  • 这种方式通过强类型DTO匹配目标结构,比直接操作JSON节点更易读、易维护;
  • 如果存在多个学校或多个班级,只需添加循环遍历逻辑即可扩展;
  • ubicazione的处理逻辑是取分组中第一个有值的记录,可根据实际需求调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:06:24