繁体   English   中英

我可以在InputStreams中使用Velocity模板吗?

[英]Can I use Velocity templates with InputStreams?

我正在处理大文件,我需要围绕base64有效负载包装XML。 我的第一个天真实现将有效负载作为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可能非常大,所以我想避免使用Stringbyte[] 是否可以将InputStream作为$body传递到我的模板中,或者我不能使用Velocity这个?

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM