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
相关产品推荐
相关产品推荐

