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

Java解析REST API嵌套JSON后,如何修正输出为预期JSON格式

问题:REST API嵌套JSON响应序列化后输出不符合预期

我需要处理REST API的嵌套JSON响应,httpsConn.getInputStream()返回的JSON内容如下:

{"data":[{"id":"1","name":"aaa","score":"90"},{"id":"2","name":"bbb","score":"85"}]}

现有Java代码:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
response = (MarkResponse)objectMapper.readValue(httpsConn.getInputStream(), MarkResponse.class);

POJO类定义:

public class MarkResponse {
    private int count;
    private List<MarkData> markData;
    // setter and getter.
}
public class MarkData {
    private String id;
    private String name;
}

当前得到的响应为:

{"headers":{},"body":"MarkResponse [count=2 markData= [MarkData [id=1, name=aaa], MarkData [id=2,name=bbb]] ]","statusCode":"ACCEPTED","statusCodeValue":202}

而我预期的响应是:

{"headers":{},"body":"MarkResponse [count=2 markData= {\"id\":\"1\",\"name\":\"aaa\"},{\"id\":\"2\",\"name\":\"bbb\"} ]","statusCode":"ACCEPTED","statusCodeValue":202}

请问需要修改哪些代码才能得到预期的输出?


解决方案

嘿,我来帮你搞定这个问题!你现在遇到的核心问题是:默认的POJOtoString()方法输出的是对象的结构化字符串,而不是你想要的JSON格式。咱们可以通过两种方式调整:

1. 手动序列化markData为JSON字符串(推荐)

这种方式更灵活,不会把序列化逻辑耦合到POJO里。在构造响应body的时候,用ObjectMapper把markData序列化成JSON格式的字符串,再拼接成你需要的格式:

// 假设你已经完成了反序列化得到response对象
ObjectMapper objectMapper = new ObjectMapper();
// 把markData序列化为JSON数组字符串
String markDataJson = objectMapper.writeValueAsString(response.getMarkData());
// 拼接成你想要的body格式
String body = String.format("MarkResponse [count=%d markData= %s ]", response.getCount(), markDataJson);
// 然后把这个body赋值给你的响应对象即可

这样生成的markDataJson就是[{"id":"1","name":"aaa"},{"id":"2","name":"bbb"}],拼接后就和你预期的格式一致了。

2. 重写POJO的toString()方法(耦合性稍高)

如果你希望直接调用response.toString()就能得到目标格式,可以重写MarkResponse和MarkData的toString()方法:

修改MarkData的toString()

public class MarkData {
    private String id;
    private String name;
    // setter and getter

    @Override
    public String toString() {
        return String.format("{\"id\":\"%s\",\"name\":\"%s\"}", id, name);
    }
}

修改MarkResponse的toString()

public class MarkResponse {
    private int count;
    private List<MarkData> markData;
    // setter and getter

    @Override
    public String toString() {
        // 把List<MarkData>转成逗号分隔的JSON格式字符串
        String markDataStr = String.join(",", markData.stream().map(MarkData::toString).toList());
        return String.format("MarkResponse [count=%d markData= %s ]", count, markDataStr);
    }
}

这样当你调用response.toString()时,就能得到你预期的格式了。不过这种方式把格式逻辑写到了POJO里,如果后续格式有变化,需要修改POJO代码,灵活性不如第一种方式。

额外注意:count字段的赋值

另外,你的原始JSON响应里并没有count字段,当前得到的count=2应该是你后续代码手动设置的吧?如果是自动反序列化的话,count会是默认值0,记得要确保count的值是正确的(比如可以通过response.setCount(response.getMarkData().size())来设置)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:58:22