Camel - 流缓存不缓存/无法转换?

2022-01-19 00:00:00 java apache-camel

读过一次后,我似乎正在失去我的内在"身体.请注意,我使用的是 Camel 的流缓存,并且输入是来自 http 组件的 json 文件.我有一个带有以下代码的处理器.

I seem to be losing my 'in' body after reading it once. Note that I am using Camel's stream caching, and that the input is a json file from the http component. I have a processor with the following code.

    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 返回一个空白字符串(非空).以下是 TRACE 级别的日志.

What I'd expect to see here is that msg1 and msg2 are the same output, However msg2 returns a blank string (not null). Here are the logs at TRACE level.

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 行 - 我的消息丢失了.
  • Line 1- The Body Type is correctly showing a cached input stream
  • Line 4- Converting to String does work to produce msg1, even though line 3, the conversion code, seems to fail with an IOException
  • Line 6- Also failing the conversion but it's important to note that the body is still a cached stream.
  • Line 7- My message is lost.

那么 msg2 去哪儿了?

So where did msg2 go?

编辑

除了下面彼得的回答之外,还有一些事情要提:

Some things to mention in addition to Peter's answer below:

Camel 的 MessageHelper 静态类有两个有用的功能:

Camel's MessageHelper static class has two useful functions:

  • resetStreamCache
  • extractBodyAsString

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

Both of which will help for this situation

推荐答案

使用流缓存允许您在不同的处理器中多次读取流,但仍然在同一个处理器中只能读取一次.

Using stream cache allows you to read streams more than once in different processors but still only once in the same processor.

我测试过:

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

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

还有:

public class MyProcessor implements Processor {
    private static final Logger LOG = LoggerFactory.getLogger(HttpStreamCache.MyProcessor.class);
    @Override
    public void process(final Exchange exchange) throws Exception {
        LOG.info("***** Body Type: " + exchange.getIn().getBody().getClass().getCanonicalName());
        LOG.info("***** In msg1  : " + exchange.getIn().getBody(String.class));
        LOG.info("***** In msg2  : " + exchange.getIn().getBody(String.class));
    }
};

打印出来:

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  :  

相关文章