3

大きなファイルを扱っており、XML を base64 ペイロードにラップする必要があります。私の最初の単純な実装では、ペイロードを として[Velocity template][0] に渡しましたが、代わりjava.lang.Stringに使用したい大きなファイルがありました。java.io.InputStream

これが私のテンプレートです:

<?xml version="1.0" encoding="UTF-8"?>
<Request>
    <AdditonalParameters>
#if( $headers.additionalParameters )
#foreach( $key in $headers.additionalParameters.keySet() )
        <Parameter>
            <Key>${key}</Key>
            <Value>${headers.additionalParameters.get($key)}</Value>
        </Parameter>
#end
#end
    </AdditonalParameters>
    <Content>${body}</Content>
</Request>

$bodyString非常に大きくなる可能性があるため、 orの使用は避けたいと思いbyte[]ます。InputStreamテンプレートにasを渡すことは可能$bodyですか、それとも Velocity を使用できませんか?

4

1 に答える 1

1

はい、これは可能です。必要なのは、行ごとに印刷する反復だけInputStringです。Velocity には- のwhileような構造がなく、ループについてしか認識していないforeachため、最も単純な実装では、反復は醜いハックのように見えます。

#foreach ($i in [0..100000])
    #set ($line = false)
    #set ($line = $body.readLine())
    #if ($line)
        ${line}
    #else
        #break
    #end
#end

ここでは、無限ループをシミュレートするために非常に大きな数値範囲が使用されています。( )#breakから抽出できる行がなくなると、ループが発生します。警告は 3 行目にあります。InputStream$body

#set (line = $body.readLine())

Velocity ではいつものように、代入の左側は、右側の値が null でない場合にのみ変更されます。には null 値が割り当てられることはないため$line、事前に設定する必要がありますfalse(によって返される文字列ではなく、ブール値readLine)。このように、が2 番目の の後に$lineまだある場合は、 が nullを返したことがわかるので、反復を終了します。false#setreadLine

このアプローチの問題は、行間に挿入されたテンプレート内の空白です。これを回避するためのいくつかのトリックがあります (こちらを参照)。また、. #foreach_ _ _ これは KISS にはなりませんが、コードをより再利用しやすくします。Listiterator()IteratorInputStream

于 2013-10-25T21:40:30.360 に答える