java Apache Camel 根据请求使用文件内容丰富消息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15947523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Apache Camel enrich message with file content on request
提问by nikagra
I'm implementing RESTful service (using CXFRS component) which should return files for some requests. Each file is fetched by its id and extension, i.e. restfulservice.com/path/file/1/pdf
. Each file once added never changes. Files should not be moved or deleted after fetching and generally they should be accessible concurrently. Here is part of my Camel context:
我正在实现 RESTful 服务(使用 CXFRS 组件),它应该为某些请求返回文件。每个文件都通过其 id 和扩展名获取,即restfulservice.com/path/file/1/pdf
. 每个文件一旦添加就永远不会改变。提取后不应移动或删除文件,通常它们应该可以同时访问。这是我的 Camel 上下文的一部分:
from("direct:fetchFile")
.process(fetchFileProcessor) // set file.id & file.extension
.bean(fileService, "fetchFile(${header.file.id}, ${header.file.extension})") // set body to filename
.setHeader("CamelFileName", simple("${body}"))
.choice()
.when(header("file.extension").isEqualTo("xml"))
.pollEnrich("file:///{{application.fileStorage.basePath}}/xml?noop=true", 500)
.when(header("file.extension").isEqualTo("pdf"))
.pollEnrich("file:///{{application.fileStorage.basePath}}/pdf?noop=true", 500)
.end()
.convertBodyTo(File.class)
.bean(responseProvider, "getResponse(${body}, 200)");
The problem with this configuration is that response has non-empty body only for second(why?) request, without timeout set service enters on eternal loop on second request with debug message
此配置的问题是响应仅针对第二个(为什么?)请求具有非空主体,没有超时设置服务在带有调试消息的第二个请求中进入永恒循环
DEBUG o.a.c.c.f.FileConsumer - Took 0.000 seconds to poll <base path>\xml
Apace Camel version is 2.10.4
Apace Camel 版本是 2.10.4
Any help would be appreciated
任何帮助,将不胜感激
UPD1:
There is warning on Content Enricherpage, saying 'pollEnrich does not access any data from the current Exchange'. But nothing changes if I add fileName=${body}
to file URL
UPD1:ContentEnricher 页面
上有警告,说“pollEnrich 不访问当前 Exchange 中的任何数据”。但是如果我添加到文件 URL没有任何变化fileName=${body}
UPD2:
It seems like pollEnrich do not support dynamic fileName
specified in URL (link). Route at current moment:
UPD2:
似乎 pollEnrich 不支持fileName
URL ( link) 中指定的动态。当前路线:
from("direct:fetchFile")
.process(fetchFileProcessor) // set file.id & file.extension
.bean(fileService, "fetchFile(${header.file.id}, ${header.file.extension})") // set body to filename
.choice()
.when(header("file.extension").isEqualTo("xml"))
.pollEnrich("file:///{{application.fileStorage.basePath}}/xml?fileName=${body}&noop=true", 500)
.setHeader("asset.type", simple(MediaType.APPLICATION_XML))
.when(header("file.extension").isEqualTo("pdf"))
.pollEnrich("file:///{{application.fileStorage.basePath}}/pdf?fileName=${body}&noop=true", 500)
.setHeader("asset.type", simple("application/pdf"))
.end()
.convertBodyTo(File.class)
.process(multipartProcessor) // add file ass attachment to multipart body and set it as body
.bean(responseProvider, "getResponse(${body}, 200)");
UPD3
I'm trying to to implement custom processor to use PollingConsumer with dynamic file names:
UPD3
我正在尝试实现自定义处理器以将 PollingConsumer 与动态文件名一起使用:
@Override
public void process(Exchange exchange) throws Exception {
Long timeout = exchange.getIn().getHeader("file.timeout", Long.class);
if (enrichUri == null) {
throw new FileNotFoundException("'file.url' header not set");
}
CamelContext context = exchange.getContext();
Endpoint endpoint = context.getEndpoint(enrichUri);
PollingConsumer consumer = endpoint.createPollingConsumer();
consumer.start();
Exchange consumedExchange;
try {
if (timeout == null || timeout < 0) {
consumedExchange = consumer.receive();
} else if (timeout == 0) {
consumedExchange = consumer.receiveNoWait();
} else {
consumedExchange = consumer.receive(timeout);
}
} catch (Exception e) {
throw new AssetNotFoundException(e);
} finally {
consumer.stop();
}
exchange.getIn().setBody(consumedExchange.getIn().getBody());
}
Now it returns file contents on first response, but on each succeeding request I got eternal loop of above log messages:
现在它在第一次响应时返回文件内容,但是在每个成功的请求中,我得到了上述日志消息的永恒循环:
DEBUG o.a.c.c.f.FileConsumer - Took 0.000 seconds to poll <base path>\xml
UPD4
I've implemented dynamic route which is added before processing and removed after it. This method is described in thispost in Apache Camel forum. Route uses above processor to consume file. The result is the same
UPD4
我已经实现了在处理之前添加并在处理之后删除的动态路由。此方法在 Apache Camel 论坛中的这篇文章中有所描述。路由使用上面的处理器来消费文件。结果是一样的
回答by nikagra
Simple way often is the best way. I refuse to deal with Apache Camel file component in this case and implemented following processor:
简单的方法往往是最好的方法。在这种情况下,我拒绝处理 Apache Camel 文件组件并实现了以下处理器:
public class FileLoadingProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
String filename = exchange.getIn().getBody(String.class); // message body contains filename
String filePath = exchange.getIn().getHeader("fileprocessor.filepath", String.class);
if (filePath == null || filename == null) {
// throw some custom exception
}
URI uri = new URI(filePath.concat(filename));
File file = new File(uri);
if (!file.exists()) {
throw new FileNotFoundException(String.format("File %s not found on %s", filename, filePath));
}
exchange.getIn().setBody(file);
}
Now it's working like a charm
现在它就像一个魅力