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

