我有一个CXFRS端点,其中诸如“GET / files / x”之类的请求应该从特定目录返回文件“x”,然后将其删除。文件从另一个进程输出,然后通过此路由快速消耗。因此,如果需要,可以对它们进行轮询并暂时保存在内存中。
以下是我的网络服务。
@Component
@Path("/")
public class WebService {
@GET
@Path("files/{id}")
public String getFile(@PathParam("id") String id) {
return null;
}
}
以下是不完整的路线。
<route>
<from uri="cxfrs://bean:webService"/>
<choice>
<when>
<simple>${in.headers.operationName} == 'getFile'</simple>
<setHeader headerName="correlationId">
<simple>mandatoryBodyAs(java.lang.String)</simple>
</setHeader>
???
</when>
<choice>
</route>
我已经调查了内容丰富模式,但这无济于事,因为富裕者内的消费者无法访问原始交换。因此,不能从输入消息动态地确定文件名。换句话说,下面的示例不会读取文件“x”,因为文件端点永远不会看到标题。
...setHeader(Exchange.FILE_NAME, "x").pollEnrich("file://dir")...
我还尝试在Web服务路由和单独的文件路由之间使用聚合器模式,聚合策略如下所示。
@Component
public class Aggregator implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
if (oldExchange == null) {
return newExchange;
} else {
oldExchange.getOut().setBody(newExchange.getIn().getBody());
return oldExchange;
}
}
}
这不起作用,因为聚合器模式似乎是“仅在”交换;通过“in out”交换,一旦消息到达聚合器,就会将回复返回给客户端,而不是在聚合完成之后。随后,我开始编写以下流程。
@Component
public class FileEnricher implements Processor {
@Value("${folder}")
private String folder;
public void process(Exchange exchange) throws Exception {
Endpoint endpoint = exchange.getContext().getEndpoint(String.format(
"file://%s?fileName=%s",
folder,
exchange.getIn().getHeader("correlationId")
));
PollingConsumer consumer = endpoint.createPollingConsumer();
PollEnricher enricher = new PollEnricher(consumer);
enricher.setTimeout(10000);
consumer.start();
enricher.process(exchange);
enricher.shutdown();
consumer.stop();
}
}
这个过程只不过是允许我动态配置内容丰富。我发现很难相信没有更好的方法来做到这一点。特别是,我担心线程化并在上下文中不断添加/删除组件/端点。
有人能建议更好地解决这个问题吗?
答案 0 :(得分:1)
只需使用java.io.File设置消息体,就可以丰富文件,例如从java bean中获取。然后将消息路由到bean:
public File whichFileToPick(@Header("id") String id) {
return new File("somedir/" + id");
}
将来pollEnrich将得到增强,因此直接在Camel路线中进行操作会更容易。 Christian想出了一个很好的想法,允许指定一个Camel表达式作为pollEnrich的uri。