0

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データの潜在的なサイズは数百メガバイトになる可能性があるため、これを行う必要があります。

問題は、END_ELEMENTイベント TextFromElementReaderの原資産を前進させることのようです。次に、基になるものを呼び出し、END_DOCUMENTイベントを取得します。テキストセグメントの終わりに到達したことを知るためにEND_ELEMENTに遭遇する必要があるようですが、これにより、基になるものが。の間違った状態のままになります。XMLStreamReaderOMElementImpl.getNextOMSibling()next()XMLStreamReaderTextFromElementReaderXMLStreamReaderOMElementImpl.getNextOMSibling()

誰かが以前にこのエラーを見たことがありますか?Axiomの使用方法に問題がありますか?

4

1 に答える 1

0

getTextAsReaderをまったく使用しなくなりました。代わりに、子テキストノードを繰り返し処理し、テキストコンテンツをそのようにチャンクで処理しました。パーサーは非合体するように構成されているため、1つの大きなテキストノードではなく、適度なサイズのテキストノードを取得します。

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;
    }
}
于 2013-01-22T03:15:57.303 に答える