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

Java.net实现RESTful服务JSON解析:重复Itm对象转Java集合

如何将重复键的非标准JSON响应映射到Java List集合?

首先,咱们得明确问题的核心:你拿到的JSON响应是非标准格式——JSON对象规范里不允许存在重复的键,不同解析器处理这种情况的行为不一致(比如Jettison可能只保留第一个Itm,Jackson默认会覆盖为最后一个),这就是你只能拿到单个Itm的原因。

下面给你两种解决方案,优先推荐第一种(如果能影响服务端的话),如果没法改服务端,就用第二种客户端兼容方案:

方案一:修改服务端返回标准JSON格式

最根本的解决办法是让服务端把重复的Itm字段改成数组形式,这是JSON的规范写法:

{"Response":{"RID":"04'34'", "Itm": [
    {"id":{"ab":"1","cd":"12"},"qw":"JK","name":"abcd "}, 
    {"id":{"ab":"2","cd":"34"},"qw":"JK","name":"asdf "}, 
    {"id":{"ab":"3","cd":"12"},"qw":"JK","name":"fghj "}
]}}

这样不管用Jettison还是Jackson,都能直接把Itm映射到List<Itm>字段,完全不需要额外处理,是最稳妥的方案。

方案二:客户端用Jackson自定义解析重复键

如果没法修改服务端,咱们可以用Jackson的特性来兼容这种非标准JSON。核心思路是用@JsonAnySetter注解捕获所有重复的Itm键,把它们收集到List里。

步骤1:定义POJO类

// 最外层的响应对象
public class MyJavaResponseObject {
    private Response Response;

    // Getter & Setter
    public Response getResponse() { return Response; }
    public void setResponse(Response response) { Response = response; }
}

// Response内部结构
public class Response {
    private String RID;
    private List<Itm> itms = new ArrayList<>();

    // 用@JsonAnySetter捕获所有未映射的属性,重点处理重复的"Itm"键
    @JsonAnySetter
    public void handleDuplicateItm(String key, Itm value) {
        if ("Itm".equals(key)) {
            itms.add(value);
        }
        // 其他未知键可以在这里忽略或记录
    }

    // Getter & Setter
    public String getRID() { return RID; }
    public void setRID(String RID) { this.RID = RID; }
    public List<Itm> getItms() { return itms; }
}

// Itm对象
public class Itm {
    private Id id;
    private String qw;
    private String name;

    // Getter & Setter
    public Id getId() { return id; }
    public void setId(Id id) { this.id = id; }
    public String getQw() { return qw; }
    public void setQw(String qw) { this.qw = qw; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

// Id对象
public class Id {
    private String ab;
    private String cd;

    // Getter & Setter
    public String getAb() { return ab; }
    public void setAb(String ab) { this.ab = ab; }
    public String getCd() { return cd; }
    public void setCd(String cd) { this.cd = cd; }
}

步骤2:配置Jackson并解析

ObjectMapper mapper = new ObjectMapper();
// 关键:允许JSON中存在重复键,否则Jackson会抛出异常或覆盖值
mapper.configure(JsonParser.Feature.ALLOW_DUPLICATE_NAMES, true);
// 忽略未知属性,避免因额外字段报错
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

// 解析JSON到POJO
MyJavaResponseObject javaObj = mapper.readValue(responseStrBuilder.toString(), MyJavaResponseObject.class);
// 现在就能拿到所有Itm对象的集合了
List<Itm> allItms = javaObj.getResponse().getItms();

原理说明

@JsonAnySetter注解会让Jackson把所有未被显式映射的属性(这里就是重复的Itm键)传递给这个方法,我们在方法里判断键名是Itm时,就把对应的对象添加到List中,这样就能收集到所有的Itm实例了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:15:53