Java 驼峰-流缓存不缓存/can';我不能皈依?

Java 驼峰-流缓存不缓存/can';我不能皈依?,java,apache-camel,Java,Apache Camel,读了一次之后,我似乎失去了我的“内在”身体。注意,我使用的是Camel的流缓存,输入是来自http组件的json文件。我有一个具有以下代码的处理器 log.debug("Body Type: " + exchange.getIn().getBody().getClass().getCanonicalName()); log.debug("In msg1:" + exchange.getIn().getBody(String.class)); log.debug("In

读了一次之后,我似乎失去了我的“内在”身体。注意,我使用的是Camel的流缓存,输入是来自http组件的json文件。我有一个具有以下代码的处理器

    log.debug("Body Type: " + exchange.getIn().getBody().getClass().getCanonicalName());
    log.debug("In msg1:"  + exchange.getIn().getBody(String.class));
    log.debug("In msg2:"  + exchange.getIn().getBody(String.class));
我希望在这里看到的是,msg1和msg2是相同的输出,但是msg2返回一个空白字符串(不是null)。以下是跟踪级别的日志

1- DEBUG com.mycompany.MyProcessor : Body Type: org.apache.camel.converter.stream.InputStreamCache
2- TRACE org.apache.camel.impl.converter.DefaultTypeConverter : Converting org.apache.camel.converter.stream.InputStreamCache -> java.lang.String with value: org.apache.camel.converter.stream.InputStreamCache@780a5cef
3- TRACE org.apache.camel.impl.converter.DefaultTypeConverter : Using converter: StaticMethodTypeConverter: public static java.lang.String org.apache.camel.converter.IOConverter.toString(java.io.InputStream,org.apache.camel.Exchange) throws java.io.IOException to convert [class org.apache.camel.converter.stream.InputStreamCache=>class java.lang.String]
4- DEBUG com.mycompany.MyProcessor : In msg1:{myJson}
5- TRACE org.apache.camel.impl.converter.DefaultTypeConverter : Converting org.apache.camel.converter.stream.InputStreamCache -> java.lang.String with value: org.apache.camel.converter.stream.InputStreamCache@780a5cef
6- TRACE org.apache.camel.impl.converter.DefaultTypeConverter : Using converter: StaticMethodTypeConverter: public static java.lang.String org.apache.camel.converter.IOConverter.toString(java.io.InputStream,org.apache.camel.Exchange) throws java.io.IOException to convert [class org.apache.camel.converter.stream.InputStreamCache=>class java.lang.String]
7- DEBUG com.mycompany.MyProcessor : In msg2:
日志中需要注意的事项:

  • 第1行-主体类型正确显示缓存的输入流
  • 第4行-转换为字符串确实可以生成msg1,即使第3行转换代码似乎因IOException而失败
  • 第6行-转换也失败,但需要注意的是,主体仍然是缓存流
  • 第7行-我的信息丢失了
那么msg2去了哪里

编辑

除了Peter的回答之外,还有以下几点需要提及:

Camel的MessageHelper静态类有两个有用的函数:

  • resetStreamCache
  • extractBodyAsString

这两种方法都有助于解决这种情况

使用流缓存允许您在不同处理器中多次读取流,但在同一处理器中仅读取一次

我测试了:

ModelCamelContext context = new DefaultCamelContext();
context.setStreamCaching(true); //!!
// ...

from("direct:start")
    .to("http://ip.jsontest.com/?callback=showMyIP")
    .process(new MyProcessor())
    .process(new MyProcessor());
以及:

这张照片是:

INFO  ***** Body Type: org.apache.camel.converter.stream.InputStreamCache
INFO  ***** In msg1  : showMyIP({"ip": "00.000.000.00"});

INFO  ***** In msg2  : 
INFO  ***** Body Type: org.apache.camel.converter.stream.InputStreamCache
INFO  ***** In msg1  : showMyIP({"ip": "00.000.000.00"});

INFO  ***** In msg2  :  

如果JSON输入流的内容不是太大,您可以将输入流转换为
ByteArrayInputStream
,这样您就可以在任何
处理器中多次读取。希望这能有所帮助。

我相信你的问题不在于输入流消失了,而在于它的读者位置是在最后一个消费点,在这种情况下,是在流的末尾

您可以使用流“倒带”方法,该方法可以将读者带到流的开头—只有在流支持的情况下

下面是一个scala代码,它提供了这样一个重置器:

object StreamResetter extends Processor {
  import org.apache.camel.util.MessageHelper
  import org.apache.camel.Exchange

  override def process(exchange: Exchange): Unit = MessageHelper.resetStreamCache(exchange.getIn)
}
然后,在您的路线上,就在第二次日志调用之前,您可以使用

process(StreamResetter)

关于。

我的工作示例:

from("direct:secondRoute")
     .to("callOtherService")
     .log("RESPONSE: ${body}")  
     .process(exchange -> {
        InputStream in = exchange.getIn().getBody(InputStream.class);
        in.reset();
     });

from("direct:firstRoute")
     .to(direct:secondRoute)
     .convertBodyTo(String.class); 

请向我们展示如何设置流缓存。我们有以下代码来重置流(在scala中)--object StreamResetter extends Processor{import org.apache.camel.util.MessageHelper import org.apache.camel.Exchange override def process(Exchange:Exchange):Unit=MessageHelper.resetStreamCache(Exchange.getIn)}那很有趣。。这是你通过调查发现的还是有记录的?
from("direct:secondRoute")
     .to("callOtherService")
     .log("RESPONSE: ${body}")  
     .process(exchange -> {
        InputStream in = exchange.getIn().getBody(InputStream.class);
        in.reset();
     });

from("direct:firstRoute")
     .to(direct:secondRoute)
     .convertBodyTo(String.class);