Jur*_*uru 3 stax jaxb spring-batch
所以我试图解析一个xml并将其解组成一个程序.这是xml的示例:
<MaintenanceTransaction:provideCommunicationEvents_BatchRequest
xmlns:MaintenanceTransaction="http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MaintenanceTransaction:maintenanceTransaction>
<MaintenanceTransaction:eventInitiatedBy>
<MaintenanceTransaction:identifier>FINACLE</MaintenanceTransaction:identifier>
</MaintenanceTransaction:eventInitiatedBy>
<MaintenanceTransaction:transactionDate>2014-06-21T19:00:32.356+01:00</MaintenanceTransaction:transactionDate>
<MaintenanceTransaction:maintenanceTransactionType>PRE-NOTIFICATION
</MaintenanceTransaction:maintenanceTransactionType>
<MaintenanceTransaction:maintenanceEntries>
<MaintenanceTransaction:hasNewValues xsi:type="MaintenanceTransaction:DepositArrangement">
<MaintenanceTransaction:enterpriseId xsi:type="MaintenanceTransaction:ArrangementIdentifier">
<MaintenanceTransaction:identifier>222000000322</MaintenanceTransaction:identifier>
<MaintenanceTransaction:enterpriseIdType>Term Deposit</MaintenanceTransaction:enterpriseIdType>
</MaintenanceTransaction:enterpriseId>
<MaintenanceTransaction:maturityDate>2014-10-08</MaintenanceTransaction:maturityDate>
</MaintenanceTransaction:hasNewValues>
</MaintenanceTransaction:maintenanceEntries>
</MaintenanceTransaction:maintenanceTransaction>
</MaintenanceTransaction:provideCommunicationEvents_BatchRequest>
Run Code Online (Sandbox Code Playgroud)
xsd定义为:
<xsd:schema xmlns:MaintenanceTransaction="http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02" elementFormDefault="qualified" attributeFormDefault="qualified">
<xsd:include schemaLocation="./commonIFWxsd/IFWXML.xsd" />
<xsd:include schemaLocation="./commonIFWxsd/Event.xsd" />
<xsd:include schemaLocation="./commonIFWxsd/Arrangement.xsd" />
<!-- end of TYPES REQUIRED FOR PARAMETERS -->
<xsd:complexType name="provideCommunicationEvents_BatchRequest">
<xsd:sequence>
<xsd:element name="maintenanceTransaction" type="MaintenanceTransaction:MaintenanceTransaction" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<!-- TYPES REQUIRED FOR PARAMETERS -->
<xsd:element name="provideCommunicationEvents_BatchRequest" type="MaintenanceTransaction:provideCommunicationEvents_BatchRequest" />
</xsd:schema>
Run Code Online (Sandbox Code Playgroud)
使用我的StaxEventItemReader和Jaxb2Marshaller的以下设置:
<bean id="uploadEventMessageReader" parent="abstractUploadEventMessageReader" scope="step">
<property name="resource" value="file:#{jobExecutionContext['fileToProcess']}"/>
<property name="fragmentRootElementName" value="maintenanceTransaction"/>
<property name="unmarshaller" ref="maintenanceTransactionUnmarshaller"/>
</bean>
<bean id="maintenanceTransactionUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" scope="step">
<property name="classesToBeBound">
<list>
<value>com.pwx.crs.informationcollection.ifw.process.model.mt.MaintenanceTransaction</value>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
但问题是我得到以下异常.
* [javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02", local:"maintenanceTransaction"). Expected elements are (none)] on step uploadEventMessages, with message: uploadEventMessagesStep.
* --stacktrace:com.pwx.crs.frwk.exp.technical.CRS2UnexpectedBatchException: An unexpected exception occurred in batch job JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException
Run Code Online (Sandbox Code Playgroud)
知道这是什么意思吗?
当我稍微更改输入xml的maintenanceTransaction开始标记时,如下所示:
<MaintenanceTransaction:maintenanceTransaction xsi:type="MaintenanceTransaction:MaintenanceTransaction">
Run Code Online (Sandbox Code Playgroud)
它确实有效.但这不是一个解决方案,因为客户端不会像这样提供输入xml.那么为什么会出现错误呢?确定维护事务处理属于哪个类似乎存在问题.
还尝试了marshaller bean定义的不同方法:
<bean id="maintenanceTransactionUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" scope="step">
<property name="contextPath" value="com.pwx.crs.informationcollection.ifw.process.model.mt"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
和
<bean id="maintenanceTransactionUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" scope="step">
<property name="classesToBeBound">
<list>
<value>com.pwx.crs.informationcollection.ifw.process.model.mt.ObjectFactory</value>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
两者的结果与第一个错误相同且相似
javax.xml.bind.UnmarshalException:意外元素(uri:" http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02 ",local:"maintenanceTransaction").预期的元素是<{ http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02 } AccessTokenLifecycleStatus> ...这里是包中的整个类列表.
但xml对xsd完全有效,因为这是事先完成的.想法,建议,...我可以尝试?
因此,在研究了代码和调试以及更多的工作后,我最终得到了一些有用的东西.我不知道为什么,因为它是一个猜测,但它的工作原理.
<bean id="maintenanceTransactionUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.pwx.crs.informationcollection.ifw.process.model.mt.MaintenanceTransaction</value>
</list>
</property>
<property name="mappedClass" value="com.pwx.crs.informationcollection.ifw.process.model.mt.MaintenanceTransaction"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,没有必要将ObjectFactory用作classesToBeBound(但必须注意它本来可以工作,但在我看来这更具可读性).真正修复它的是添加mappedClass.
从调试时我在代码中看到的内容(我无法检查代码f UnmarshallingImpl,因为这是rt.jar的一部分,即使它是jre的一部分也不公开...)classesToBeBound参数用于为unmarshaller创建jaxbContext,并将mappedClass作为expectedType传递给此unmarshaller.但是当没有提供并且ObjectFactory用作参数时,错误清楚地显示了预期类的列表,并且存在适用的类...可能是unmarshaller中的错误,也许是我不理解的东西.但我的根本问题已经解决了.
这是我的理论.
什么mappedClass实际上做的是解组方法从切换unmarshaller.unmarshal(source)到unmarshaller.unmarshal(source, this.mappedClass).这称为"部分解组",即无论元素名称如何,您都可以从某个元素解组已知类.
所以,正如你所说,这适合你.它并非没有mappedClass.这意味着您缺少根元素的元素声明.这也很好地与您报告的错误相符:
javax.xml.bind.UnmarshalException: unexpected element
(uri:"http://www.pwx.com/Interface/CRS/MaintenanceTransaction_v02",
local:"maintenanceTransaction"). Expected elements are (none)
Run Code Online (Sandbox Code Playgroud)
其中说的基本相同.
这也是正确的.由于您的架构没有声明全局元素maintenanceTransaction,仅用于provideCommunicationEvents_BatchRequest.
所以,基本上你是解组错误的元素.并且由于您的架构没有声明,因此失败.但是如果你确切地指定了你想要的类型(从而"明确地"提供声明),那么它就可以了.
接下来,问题是,为什么要解组错误的元素.我猜这是因为你有
<property name="fragmentRootElementName" value="maintenanceTransaction"/>
Run Code Online (Sandbox Code Playgroud)
这可能指向unmarshaller使用maintenanceTransaction元素作为根元素.所以unmarshaller应用于错误的元素.
使用contextPath,添加更多绑定类等没有帮助,因为它没有添加元素声明maintenanceTransaction.
现在,如何解决这个问题.我看到以下选项:
maintenanceTransaction您的架构添加全局元素@XmlRootElementforMaintenanceTransactionfragmentRootElementName,unmarshalprovideCommunicationEvents_BatchRequestmappedClass如果你在这里处理一个特定的案例,maintenanceTransaction那么我会使用 fragmentRootElementName/ mappedClasscombo.就像你现在一样.
| 归档时间: |
|
| 查看次数: |
1857 次 |
| 最近记录: |