当输入为InputStreamCache时,Camel Xslt中的prolog中出现意外错误

9bfwbjaz  于 5个月前  发布在  Apache
关注(0)|答案(1)|浏览(58)

从3.17版本开始,Camel有自动转换到流缓存的功能。升级时(从3.14版本升级到4.0.2版本),我们面临一个奇怪的问题。
我们使用Saxon Xslt组件来转换XML数据。以前Exchange Input的类型是byte[],现在它的类型是InputStreamCache。这是预期的,应该在没有任何更改的情况下工作。但是当Exchange被转换时,我们得到:
第一个月
这表明转换正在空输入上运行。即InputStreamCache为空(它不是)。
这里是异常的完整堆栈跟踪,以供参考:

net.sf.saxon.trans.XPathException: Error reported by XML parser: Unexpected EOF in prolog
 at [row,col {unknown-source}]: [1,0]
    at net.sf.saxon.pull.StaxBridge.next(StaxBridge.java:205)
    at net.sf.saxon.pull.PullFilter.next(PullFilter.java:98)
    at net.sf.saxon.pull.PullPushTee.next(PullPushTee.java:73)
    at net.sf.saxon.pull.PullConsumer.consume(PullConsumer.java:42)
    at net.sf.saxon.pull.PullPushCopier.copy(PullPushCopier.java:44)
    at net.sf.saxon.pull.PullSource.deliver(PullSource.java:95)
    at net.sf.saxon.pull.ActiveStAXSource.deliver(ActiveStAXSource.java:61)
    at net.sf.saxon.event.Sender.send(Sender.java:104)
    at net.sf.saxon.Controller.makeSourceTree(Controller.java:1306)
    at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:342)
    at net.sf.saxon.jaxp.TransformerImpl.transform(TransformerImpl.java:75)
    at org.apache.camel.component.xslt.XsltBuilder.process(XsltBuilder.java:123)
    at org.apache.camel.support.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:93)
    at org.apache.camel.component.xslt.XsltEndpoint.onExchange(XsltEndpoint.java:120)

字符集
当我们切换回旧的功能时,
camelContext.setStreamCaching(false);
一切都按预期进行。

  • 我们是否错过了Camel中的一些配置选项来使其工作?
  • 我们怎样才能查明异常的根本原因呢?
  • 是否有示例或测试验证Saxon Xslt使用InputStreamCache作为输入?

在深入挖掘之后,这里有一些评论:
事实证明,在此之前,我们在路线的某个地方执行String body = exchange.getIn().getBody(String.class);
由于某种原因,在执行此操作时InputStreamCache出现了问题。我们可以看到Stream的底层“pos”被更新到流的末尾。因此,在将Stream复制到StaxSource的某个时刻,它会从“pos”复制到末尾。由于我们已经在末尾,因此没有任何内容被复制到StaxSource。
我们发现这有助于
String inBody = MessageHelper.extractBodyAsString(exchange.getIn());
以及MessageHelper.resetStreamCache(exchange.getIn());
然而,不确定这是否是InputStreamCache的工作方式?Camel关于这个主题的文档相当粗略。

snz8szmq

snz8szmq1#

这是意料之中的,就好像你写了自己的代码,用你做的代码行把正文读成String一样。而且它是基于流的,那么你需要在之后重置流。这在EIP之间的路由引擎中也会自动发生,所以如果你在调用下一个EIP之前在处理器中这样做,那么Camel路由引擎应该会自动重置它。

相关问题