我在 Axis2 中使用 Axiom 从 SOAP 消息的大型 base64Binary 部分中提取文本。我的接收器没有使用 MTOM,而是OMElement.getTextAsStream( false )
用来提取文本。代码看起来像这样:
final Iterator<OMElement> childrenIterator = uploadFile.getChildElements();
while ( childrenIterator.hasNext() )
{
final OMElement element = childrenIterator.next();
if ( "fileID".equals( element.getLocalName() ) )
{
fileID = element.getText();
}
// fileContent contains a large base64Binary block
else if ( "fileContent".equals( element.getLocalName() ) )
{
Reader reader = element.getTextAsStream( false );
final char[] buf = new char[BUFFER_SIZE];
int len = 0;
while ( (len = reader.read( buf ) ) >= 0 )
{
if ( len > 0 )
{
// Process chunk here
}
}
}
}
示例 XML 看起来像
<uploadFile>
<fileID>id</fileID>
<fileContent>~500kB of base64 data</fileContent>
</uploadFile>
childrenIterator.hasNext()
在读取 base64Binary 数据后,我在线上遇到了这个异常:
Caused by: org.apache.axiom.om.OMException: Parser has already reached end of the document. No siblings found
at org.apache.axiom.om.impl.llom.OMElementImpl.getNextOMSibling(OMElementImpl.java:359)
at org.apache.axiom.om.impl.traverse.OMChildrenIterator.getNextNode(OMChildrenIterator.java:36)
at org.apache.axiom.om.impl.traverse.OMAbstractIterator.hasNext(OMAbstractIterator.java:69)
at org.apache.axiom.om.impl.traverse.OMFilterIterator.hasNext(OMFilterIterator.java:54)
我做了一些调查,这肯定与我false
在调用时设置缓存有关getTextAsStream()
。我需要这样做,因为 base64 数据的潜在大小可能是数百兆字节。
问题似乎在于TextFromElementReader
将底层推进XMLStreamReader
到 END_ELEMENT 事件。 OMElementImpl.getNextOMSibling()
然后调用next()
底层证券XMLStreamReader
并获取 END_DOCUMENT 事件。似乎TextFromElementReader
需要遇到 END_ELEMENT 才能知道它已经到达文本段的末尾,但这会使底层代码XMLStreamReader
处于错误的状态OMElementImpl.getNextOMSibling()
。
有没有人见过这个错误?我使用 Axiom 的方式有问题吗?