Camel

您所在的位置:网站首页 camels的中文翻译 Camel

Camel

2024-06-22 12:40| 来源: 网络整理| 查看: 265

Camel 为使用许多不同的通信技术实现的端点提供开箱即用的支持。下面是 Camel 支持的端点技术的一些示例。

JMS 队列。Web 服务。一个文件(本文样例)。文件可能听起来像是不太可能的终结点类型,直到您意识到在某些系统中,一个应用程序可能会将信息写入文件,而稍后,另一个应用程序可能会读取该文件。FTP 服务器。电子邮件地址。客户端可以向电子邮件地址发送消息,服务器可以从邮件服务器读取传入邮件。POJO(普通旧 Java 对象)。 使用案例

基于文件的camel的使用案例

pom.xml 4.0.0 it.luke Camel_Pro 1.0-SNAPSHOT org.apache.camel camel-core 2.25.1 1.从目录读取并写入另一个目录

from(“file://inputdir/?delete=true”).to(“file://outputdir”)

package it.luke.camel_fileTofile; import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; /** * @author luke * @date 2020/11/70:33 */ public class CamelFile { public static void main(String[] args) { //创建一个CamelContext对象 CamelContext camelContext = new DefaultCamelContext(); //定义路由规则 try { camelContext.addRoutes(new RouteBuilder() { public void configure() { //读取指定目录的文件,写入到指定的输出目录中 ?后拼接配置参数(delete=true)写入后删除源文件 from("file://D:\\Server\\Camel_Pro\\testData\\input\\?delete=true") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\"); } }); //启动线程 camelContext.start(); Thread.sleep( 5000); //关闭线程 camelContext.stop(); } catch (Exception e) { e.printStackTrace(); } } }

在这里插入图片描述

在这里插入图片描述

2.递归地从目录读取并写入另一个目录

路由:from(“file://inputdir/?recursive=true&delete=true”).to(“file://outputdir”)

camelContext.addRoutes(new RouteBuilder() { public void configure() { //读取指定目录的文件,写入到指定的输出目录中 ?后拼接配置参数(recursive=true)递归采集目录下的文件 from("file://D:\\Server\\Camel_Pro\\testData\\input\\?delete=true&recursive=true") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\"); } });

在这里插入图片描述

在这里插入图片描述

补充:delete=true 虽然可以删除源文件,但是并不能删除源目录

如果仅需要采集文件而不需要目录结构的话,可以在输出路由添加参数?flatten=true

from("file://D:\\Server\\Camel_Pro\\testData\\input\\?delete=true&recursive=true") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\?flatten=true");

在这里插入图片描述

便可以得到平铺后的文件

3.从目录读取并处理 JAVA 中的消息

提取目录下的文件的内容,经过处理后,写入到另一个文件中

package it.luke.camel_fileTofile; import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; /** * @author luke * @date 2020/11/71:10 */ public class CamelFileObj { public static void main(String[] args) { //创建一个CamelContext对象 CamelContext camelContext = new DefaultCamelContext(); //定义路由规则 try { camelContext.addRoutes(new RouteBuilder() { public void configure() { from("file://D:\\Server\\Camel_Pro\\testData\\input\\").process(new Processor() { public void process(Exchange exchange) throws Exception { Object body = exchange.getIn().getBody(String.class); System.out.println(body); exchange.getMessage().setBody("我是重新处理过的数据"+body); // do some business logic with the input body } }).to("file://D:\\Server\\Camel_Pro\\testData\\output\\?flatten=true"); } }); //启动线程 camelContext.start(); Thread.sleep( 5000); //关闭线程 camelContext.stop(); } catch (Exception e) { e.printStackTrace(); } } }

在这里插入图片描述

在这里插入图片描述

可以看到写入内容已经被我们修改了

4.通过相对于最终目标的临时目录写入文件

写入临时目录,然后通过原子操作,将数据直接移动到目的目录,主要是为了防止正在写入时被其它程序异常读取,这样可以保证数据的完整性

to(“file:///var/myapp/finalDirectory?tempPrefix=/…/filesInProgress/”);

camelContext.addRoutes(new RouteBuilder() { public void configure() { //读取指定目录的文件,写入到指定的输出目录中 ?后拼接配置参数tempPrefix=/../filesInProgress/ 将文件的写入操作指向临时目录以作原子转移操作 from("file://D:\\Server\\Camel_Pro\\testData\\input\\?delete=true&recursive=true") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\?tempPrefix=/../filesInProgress/"); } });

在这里插入图片描述

在这里插入图片描述

5.对文件名使用表达式

from(“file://inbox?move=backup/ d a t e : n o w : y y y y M M d d / {date:now:yyyyMMdd}/ date:now:yyyyMMdd/{file:name}”).to("…");

注意move参数和delete不能共存

camelContext.addRoutes(new RouteBuilder() { public void configure() { //读取指定目录的文件,写入到指定的输出目录中 ?后拼接配置参数move=backup/${date:now:yyyyMMdd}/${file:name} 在读取完文件后将文件转移到指定目录 from("file://D:\\Server\\Camel_Pro\\testData\\input\\?recursive=true&move=backup/${date:now:yyyyMMdd}/${file:name}") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\?tempPrefix=/../filesInProgress/"); } });

move常用来指定文件在哪个时间段完成读取,读取的内容是什么,是问题回溯的一大利器

6.避免重复读取同一文件(幂等使用者)+ 定时调度

from(“file://inbox?idempotent=true”).to("…");

按照一定的规则拒绝重复读取

为了方便观察,这边开启定时任务

添加依赖

org.apache.camel camel-quartz2 2.16.2 package it.luke.camel_fileTofile; import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; /** * @author luke * @date 2020/11/712:06 */ public class CamelQuzFile { public static void main(String[] args) { //创建一个CamelContext对象 CamelContext camelContext = new DefaultCamelContext(); //定义路由规则 try { camelContext.addRoutes(new RouteBuilder() { public void configure() { //配置定时器quartz2:Demo?cron=1/10 * * * * ? from("quartz2:Demo?cron=1/10 * * * * ?"). from("file://D:\\Server\\Camel_Pro\\testData\\input\\") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\"); } }); //启动线程 camelContext.start(); synchronized (CamelQuzFile.class) { CamelQuzFile.class.wait(); } } catch (Exception e) { e.printStackTrace(); //关闭线程 try { camelContext.stop(); } catch (Exception e1) { e1.printStackTrace(); } } } }

没有添加幂等的情况下,往input目录里面添加重复名字的文件是会重复读取写入的

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

故添加幂等

camelContext.addRoutes(new RouteBuilder() { public void configure() { //读取指定目录的文件,写入到指定的输出目录中 ?后拼接配置参数idempotent=true幂等文件名,通过判断文件名是否一致,拒绝重复读取 from("quartz2:Demo?cron=1/10 * * * * ?"). from("file://D:\\Server\\Camel_Pro\\testData\\input\\?idempotent=true") .to("file://D:\\Server\\Camel_Pro\\testData\\output\\"); }

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这边在输入目录同时写入两份内容一样的文件1.log和2.log

在这里插入图片描述

调度时间到了之后,发现1.log 内容并没有刷新过来,因为默认的幂等是按照文件的绝对路径的

此外可以通过&idempotentKey= f i l e : n a m e − {file:name}- file:name−{file:size}

来指定幂等的key

7.使用过滤器

路由中使用filter可以对传输的数据 进行过滤

public FilterDefinition filter(@AsPredicate Predicate predicate) { FilterDefinition filter = new FilterDefinition(predicate); this.addOutput(filter); return filter; } //new Predicate() 需要传入一个对象,则是一个抽象接口,需要重写matches方法,因为这边只调用一次,所以这边采用匿名内部类的方式 camelContext.addRoutes(new RouteBuilder() { public void configure() { //读取指定目录的文件,写入到指定的输出目录中 //通过filter进行message的过滤 from("file://D:\\Server\\Camel_Pro\\testData\\input\\").filter( new Predicate() { public boolean matches(Exchange exchange) { String body = exchange.getIn().getBody(String.class); System.out.println(body.length()); if (body.contains("filter")) { System.out.println(body); return true; } return false; } } ) .to("file://D:\\Server\\Camel_Pro\\testData\\output\\"); } });

在这里插入图片描述

这边在新建两个测试文件,一个文件内容带有filter字样用于过滤

在这里插入图片描述

可以看到只有带有filter的文件进行了路由写入

控制条件可以根据自己的需求进行修改

废话:

个人觉得camel是一个特别适合企业集成使用的技术,提供的高级抽象有点类似SpringJPAData

目的就是将很多不同协议的数据通道,通过以相类似的路由形式表示出来使用

这里只总结了个人觉得比较常用的用法,更多的参数可以参考官网

更多内容参考官网:https://camel.apache.org/components



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3