3

我正在处理大文件,我需要将 XML 包装在 base64 有效负载周围。我的第一个简单实现将有效负载作为 a 传递java.lang.String到 [Velocity 模板][0] 中,但我想使用大文件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>

$body可能非常大,所以我想避免使用Stringor byte[]。是否可以将InputStreamas传递$body到我的模板中,或者我不能为此使用 Velocity?

4

1 回答 1

1

是的,这是可以做到的。所需要的只是InputString逐行打印您的迭代。由于 Velocity 缺少类似while- 的构造并且只知道foreach循环,因此迭代在其最简单的实现中看起来像一个丑陋的 hack:

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

这里使用一个非常大的数值范围来模拟无限循环。#break当无法从InputStream( ) 中提取更多行时,循环将执行$body。第三行有一个警告:

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

与 Velocity 中的往常一样,分配的左侧仅在右侧的值不为空时才会更改。由于$line永远不会被分配空值,我们需要将其预先设置为false(布尔值,而不是返回的字符串readLine)。这样,如果$line仍然false在 second 之后#set,我们知道readLine返回 null 并且是时候退出迭代了。

这种方法的一个问题是模板中插入行之间的空白。有一些技巧可以避免这种情况(见这里)。此外,#foreach可以通过创建一个Listiterator()方法返回一个Iterator迭代InputStream. 这将减少 KISS,但它会使您的代码更可重用。

于 2013-10-25T21:40:30.360 回答