如何将JSON对象转为JSON数组并映射到自定义ReportResponse POJO
解决方案
要完成从外部API响应到目标JSON结构的转换,我们需要修正现有代码中的映射逻辑,并正确封装结果。以下是分步实现方案:
1. 核心问题分析
现有代码的主要问题:
- 未将JSON对象的键映射到
ReportResponse的name字段 - 返回的是原始API响应而非转换后的结果
- GET请求携带了不必要的请求体
2. 方案一:使用org.json库(保持原有技术栈)
直接基于你当前使用的org.json库修改代码,实现正确映射:
import org.json.JSONArray; import org.json.JSONObject; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import java.util.Iterator; public String getReportList(String clientApiId) { try { final String url = "https://chapi.cloudhealthtech.com/olap_reports/custom?client_api_id=" + clientApiId; RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey); headers.add(HttpHeaders.ACCEPT, "application/json"); // GET请求无需请求体,传入null即可 HttpEntity<String> requestEntity = new HttpEntity<>(null, headers); ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); JSONObject originalObj = new JSONObject(responseEntity.getBody()); JSONObject linksObj = originalObj.getJSONObject("links"); Iterator<String> keyIterator = linksObj.keys(); JSONArray responseArray = new JSONArray(); while (keyIterator.hasNext()) { String reportName = keyIterator.next(); JSONObject hrefObj = linksObj.getJSONObject(reportName); // 映射到ReportResponse POJO ReportResponse report = new ReportResponse(); report.setName(reportName); report.setHref(hrefObj.getString("href")); // 转换为JSON对象并加入数组 JSONObject reportJson = new JSONObject(); reportJson.put("name", report.getName()); reportJson.put("href", report.getHref()); responseArray.put(reportJson); } // 封装最终响应结构 JSONObject finalResponse = new JSONObject(); finalResponse.put("response", responseArray); return finalResponse.toString(); } catch (Exception e) { e.printStackTrace(); // 返回标准化错误响应 return new JSONObject().put("error", "处理报告列表失败:" + e.getMessage()).toString(); } }
3. 方案二:使用Jackson(Spring推荐方式)
利用Spring默认的Jackson库实现更简洁的POJO映射,同时创建响应包装类:
3.1 创建响应包装类
import java.util.List; public class ReportListResponse { private List<ReportResponse> response; public ReportListResponse() {} public ReportListResponse(List<ReportResponse> response) { this.response = response; } // Getter和Setter public List<ReportResponse> getResponse() { return response; } public void setResponse(List<ReportResponse> response) { this.response = response; } }
3.2 修改业务方法
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.type.TypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; import java.util.List; import java.util.Map; public ReportListResponse getReportList(String clientApiId) { ObjectMapper objectMapper = new ObjectMapper(); try { final String url = "https://chapi.cloudhealthtech.com/olap_reports/custom?client_api_id=" + clientApiId; RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey); headers.add(HttpHeaders.ACCEPT, "application/json"); HttpEntity<String> requestEntity = new HttpEntity<>(null, headers); ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); // 解析响应并提取links节点 JsonNode rootNode = objectMapper.readTree(responseEntity.getBody()); JsonNode linksNode = rootNode.get("links"); // 转换为键值对映射 Map<String, JsonNode> linksMap = objectMapper.convertValue(linksNode, new TypeReference<>() {}); // 映射到ReportResponse列表 List<ReportResponse> reportList = new ArrayList<>(); for (Map.Entry<String, JsonNode> entry : linksMap.entrySet()) { ReportResponse report = new ReportResponse(); report.setName(entry.getKey()); report.setHref(entry.getValue().get("href").asText()); reportList.add(report); } return new ReportListResponse(reportList); } catch (Exception e) { e.printStackTrace(); // 可自定义错误响应类返回 throw new RuntimeException("获取报告列表失败:" + e.getMessage()); } }
注:如果该方法是
@RestController的接口方法,直接返回ReportListResponse即可,Spring会自动将其序列化为目标JSON结构。
4. 关键改进点
- 正确将JSON对象的键映射到
ReportResponse的name字段 - 移除GET请求中不必要的请求体
- 封装结果为
{"response": [...]}的目标结构 - 增加异常处理,返回标准化错误响应
内容的提问来源于stack exchange,提问作者rsharma
相关产品推荐
相关产品推荐

