使用EclipseLink MOXY反序列化JSON数组时仅获最后一条数据的问题
问题解决:EclipseLink MOXY动态反序列化JSON数组仅获取最后一条数据
问题原因
- 元数据容器类型错误:OXM中
Data类的releves属性指定container-type为java.util.Collections,这是工具类而非可实例化的容器实现,MOXY无法正确创建集合存储多个元素,导致后续元素覆盖前一个。 - 反序列化目标类型错误:代码中直接将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
相关产品推荐
相关产品推荐

