我在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>
在读取base64Binary数据后,我在childrenIterator.hasNext()
行上收到此异常:
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的方式有问题吗?
答案 0 :(得分:0)
我最终根本没有使用getTextAsReader。相反,我遍历子文本节点并以这种方式处理文本内容。解析器配置为非合并,因此我得到合理大小的文本节点而不是一个大的。
OMNode child = omElement.getFirstOMChild();
while ( child != null )
{
if ( child instanceof OMText )
{
// process 'child' text here
final OMNode nextSibling = child.getNextOMSibling();
child.detach(); // detach from OM to keep memory usage low
child = nextSibling;
}
}