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

使用EclipseLink MOXY反序列化JSON数组时仅获最后一条数据的问题

问题原因

  1. 元数据容器类型错误:OXM中Data类的releves属性指定container-type为java.util.Collections,这是工具类而非可实例化的容器实现,MOXY无法正确创建集合存储多个元素,导致后续元素覆盖前一个。
  2. 反序列化目标类型错误:代码中直接将JSON反序列化为Releves类型,但输入JSON的根结构是包含releves数组的Data对象,指定错误类型会导致MOXY只解析最后一个数组元素。

修正步骤

1. 修正JSON元数据模型

将Data类的releves属性的container-type改为java.util.List:

{
   "package-name" : "com.deep.eclipse.link",
   "xml-schema" : {
      "element-form-default" : "QUALIFIED",
      "namespace" : "http://www.com.deep.eclipse.link/data"
   },
   "java-types" : {
      "java-type" : [ {
         "name" : "Data",
         "xml-type" : {
            "prop-order" : "releves"
         }, 
         "xml-root-element" : {},
         "java-attributes" : {
            "xml-element" : [
                {"java-attribute" : "releves", "name" : "releves" , "type" :"com.deep.eclipse.link.Releves", "container-type":"java.util.List"}
            ]
         }
      },{
         "name" : "Releves",
         "java-attributes" : {
            "xml-element" : [ 
                {"java-attribute" : "name", "xml-path" : "name/text()"},
                {"java-attribute" : "date", "xml-path" : "date/text()"},
                {"java-attribute" : "data", "xml-path" : "data/text()"}
            ]
         }
      }  ]
   }
}

2. 修正反序列化代码

将反序列化的目标类型改为Data,并从Data对象中获取releves列表:

Map<String, Object> properties = new HashMap<>();
properties.put(JAXBContextProperties.MEDIA_TYPE,"application/json");
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "src/main/resources/bank.statements.json");
properties.put(JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
ClassLoader myClassLoader =  Thread.currentThread().getContextClassLoader();
        
DynamicJAXBContext jc = DynamicJAXBContextFactory.createContextFromOXM(myClassLoader, properties);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
unmarshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, true);
// 改为获取Data类的类型
Class dataClass = jc.newDynamicEntity("com.deep.eclipse.link.Data").getClass();
JAXBElement<DynamicEntity> element = unmarshaller.unmarshal(new StreamSource(new File("src/main/resources/input.bank.statement.json")), dataClass);
DynamicEntity dataEntity = element.getValue();
// 获取releves列表
List<DynamicEntity> relevesList = (List<DynamicEntity>) dataEntity.get("releves");
// 遍历输出所有元素
for(DynamicEntity releve : relevesList){
    System.out.println(releve);
}

验证说明

修正后,MOXY会正确创建List<Releves>存储JSON数组中的所有元素,反序列化目标类型匹配JSON根结构,就能完整获取两个Releves对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 06:14:52