Java 如何拆分包含apache camel中文件列表的exchange并将每个文件写入文件系统
正如问题所说,我正在尝试在聚合并拆分文件后将一组文件(本例中为3个)写入文件系统 我怎样才能在骆驼里做到这一点?我使用的是2.16.5,因为这是我正在研究的项目的骆驼版本 在我看来,这是应该做到这一点的代码:Java 如何拆分包含apache camel中文件列表的exchange并将每个文件写入文件系统,java,apache-camel,Java,Apache Camel,正如问题所说,我正在尝试在聚合并拆分文件后将一组文件(本例中为3个)写入文件系统 我怎样才能在骆驼里做到这一点?我使用的是2.16.5,因为这是我正在研究的项目的骆驼版本 在我看来,这是应该做到这一点的代码: // reads public class StringRoute extends RouteBuilder { public void configure() throws Exception { from("direct:readStrings")
// reads
public class StringRoute extends RouteBuilder {
public void configure() throws Exception {
from("direct:readStrings")
.split(body())
.to("file:input?fileExist=Append&fileName=${body}.txt");
// appending each message to diff file
}
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy;
public class AggregatorRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("file:input")
.aggregate(new GroupedExchangeAggregationStrategy())
.constant(true)
.completionSize(3)
.to("direct:splitFiles");
from("direct:splitFiles")
.split(body())
.to("direct:writeFiles");
}
}
public class FileWriter extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:writeFiles")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println("In FileWriter: " + exchange.getIn().getBody());
}
})
.to("file:output?fileName=${body}.txt");
}
}
// Main
import routes.AggregatorRoute;
import routes.FileWriter;
import routes.StringRoute;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.impl.DefaultCamelContext;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
CamelContext camelContext = new DefaultCamelContext();
try {
camelContext.addRoutes(new StringRoute());
camelContext.start();
ProducerTemplate producerTemplate = camelContext.createProducerTemplate();
List<String> list = new ArrayList<String>();
String a = "abc";
String b = "cdb";
String c = "efg";
list.add(a); list.add(b); list.add(c);
producerTemplate.sendBody("direct:readStrings", list);
camelContext.addRoutes(new AggregatorRoute());
camelContext.addRoutes(new FileWriter());
Thread.sleep(10000);
camelContext.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
//读取
公共类StringRoute扩展了RouteBuilder{
public void configure()引发异常{
from(“direct:readStrings”)
.split(body())
.to(“file:input?fileExist=Append&fileName=${body}.txt”);
//将每条消息附加到diff文件
}
导入org.apache.camel.builder.RouteBuilder;
导入org.apache.camel.processor.aggregate.GroupedExchangeAgregationStrategy;
公共类AggregatorRoute扩展RouteBuilder{
@凌驾
public void configure()引发异常{
从(“文件:输入”)
.aggregate(新的GroupedExchangeAgregationStrategy())
.常数(真)
.completionSize(3)
。至(“直接:拆分文件”);
来自(“直接:拆分文件”)
.split(body())
。致(“直接:书面文件”);
}
}
公共类FileWriter扩展了RouteBuilder{
@凌驾
public void configure()引发异常{
来自(“直接:写入文件”)
.进程(新处理器(){
@凌驾
公共作废进程(Exchange)引发异常{
System.out.println(“文件写入程序中:+exchange.getIn().getBody());
}
})
.to(“file:output?fileName=${body}.txt”);
}
}
//主要
导入routes.AggregatorRoute;
导入routes.FileWriter;
导入routes.StringRoute;
导入org.apache.camel.CamelContext;
导入org.apache.camel.ProducerTemplate;
导入org.apache.camel.impl.DefaultCamelContext;
导入java.util.ArrayList;
导入java.util.List;
公共班机{
公共静态void main(字符串[]args){
CamelContext CamelContext=新的DefaultCamelContext();
试一试{
camelContext.addRoutes(新的StringRoute());
camelContext.start();
ProducerTemplate ProducerTemplate=camelContext.createProducerTemplate();
列表=新的ArrayList();
字符串a=“abc”;
字符串b=“cdb”;
字符串c=“efg”;
列表.添加(a);列表.添加(b);列表.添加(c);
sendBody(“direct:readStrings”,list);
camelContext.addRoutes(新的AggregatorRoute());
camelContext.addRoutes(新的FileWriter());
睡眠(10000);
camelContext.stop();
}捕获(例外e){
e、 printStackTrace();
}
}
如您所见,输出目录中没有任何文件
您必须获得异常endpoint:endpoint上没有可用的使用者[direct://splitFiles]因为direct:splitFiles的定义实际上在下面,所以在文件:输入中访问它 所以我把定义作为第一步
import java.util.ArrayList;
import java.util.List;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.processor.aggregate.AggregationStrategy;
public class AggregatorRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:splitFiles")
.split(body())
.convertBodyTo(String.class)
.to("direct:writeFiles")
;
from("file:input")
.convertBodyTo(String.class)
.log("current message:: ${body}")
.aggregate(new AggregationStrategy() {
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
String newMessage=newExchange.getIn().getBody(String.class);
List<String> messageList=null;
if(oldExchange == null) {
messageList=new ArrayList<String>();
}
if(oldExchange != null && newExchange!=null) {
messageList=oldExchange.getIn().getBody(List.class);
}
messageList.add(newMessage);
newExchange.getOut().setBody(messageList);
return newExchange;
}
})
.constant(true)
.completionSize(3)
.log("current message:: ${body}")
.to("direct:splitFiles")
;
}
}
您是否收到任何错误日志消息?您能告诉我们您的代码工作到什么程度以及数据在哪里被卡住或丢失吗?错误日志位于result.png中。没有错误发生。问题是输出目录中没有任何文件(请参阅附图).是的,但输出目录是经过3次路由后的最终输出。输入目录如何?文件是否写入其中?聚合器是否再次使用它们?聚合器是否创建输出消息?您只需说“没有输出,它不工作”。做一些研究,找出它工作的距离和停止工作的位置,然后在你的问题中写下这些事实。否则这就像在大海捞针一样。@burki,亲爱的,看看main。我创建了一个字符串列表。使用生产者模板将该列表发送到StringRoute。从那里,它将写入3个文件以输入->聚合FileWriter中的s->splits->problem(它应该写入到输出)Main说明了它应该做什么,而不是实际工作的内容。因此,如果说一切都可以工作,则可以在FileWriter中看到输出:“+exchange.getIn().getBody()用于聚合文件,但它不会将文件写入
输出
?不,我没有收到该异常。我没有收到任何异常。唯一的问题是文件没有写入输出文件夹。然后将聚合策略更改为GroupedMessageAggregationStrategy。我修改了您的程序,并能够在Output文件夹中可以看到三个文件。如果我更改聚合策略,它确实可以工作,但前提是我还添加了.convertBody(String.class)在聚合发生之前。有什么想法吗?为什么旧的聚合策略不起作用?顺便说一句,我提到我使用的是camel 2.16.5,对于MessageAggregation,您需要更新的版本。很抱歉,我使用的是最新的camel,并在此基础上尝试了您的程序。GroupedExchangeAgregationStrategy不起作用的原因是它会起作用拥有Exchange信息的聚合数组。在实际拆分之前,您必须有一个代码从Exchange数组中提取数据。由于GroupedMessageAggregationStrategy不是2.16.5的一部分,因此您可以实现自己的聚合策略。使用自定义聚合策略更新了答案
camelContext.addRoutes(new FileWriter());
camelContext.addRoutes(new AggregatorRoute());