import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.impl.DefaultCamelContext;
public final class CamelJmsToBean {
private CamelJmsToBean () {
}
public static void main(String args[]) throws Exception {
CamelContext context = new DefaultCamelContext();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
context.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.addRoutes(new RouteBuilder() {
public void configure() {
//from("test-jms:queue:test.queue").to("file://test");
from("test-jms:queue:test.queue").bean(new ProcMsg(), "show");
}
});
ProducerTemplate template = context.createProducerTemplate();
context.start();
for (int i = 0; i < 3; i++) {
template.sendBody("test-jms:queue:test.queue", "这个消息: " + (i+1));
}
Thread.sleep(100);
context.stop();
}
}
import java.util.Date;
public class ProcMsg {
public ProcMsg(){
super();
}
public void show(Object v){
System.out.println(new Date()+":"+v);
}
}
//用配置方式设置 消息的处理步骤
<route id="move-airMonitor">
<from uri="timer:airMonitor?period=10m;delay=10000"/>
<transform>
<method ref="lastBean" method="getLast('airall')"/>
</transform>
<log message="last query airMonitor: ${body}"/>
<to uri="bean:sqlAirFrom?method=select('select_airall','airall')"/>
<!-- <log message="airMonitor read data: ${body}"/> -->
<to uri="bean:airBean?method=moveDataBatch(${body},'exists_airall','insert_airall','update_airall','type_airall')"/>
<to uri="bean:lastBean?method=updateLastA(${body},'airall')"/>
<log message="AirMonitor update result: ${body}"/>
</route>
// Exchange 数据的 使用
Bean Binding
Bean Binding in Camel defines both which methods are invoked and also how the Message is converted into the parameters of the method when it is invoked.
Choosing the method to invoke
The binding of a Camel Message to a bean method call can occur in different ways, in the following order of importance:
- if the message contains the header CamelBeanMethodName then that method is invoked, converting the body to the type of the method's argument.
- From Camel 2.8 onwards you can qualify parameter types to select exactly which method to use among overloads with the same name (see below for more details).
- From Camel 2.9 onwards you can specify parameter values directly in the method option (see below for more details).
- you can explicitly specify the method name in the DSL or when using POJO Consuming or POJO Producing
- if the bean has a method marked with the
@Handler
annotation, then that method is selected - if the bean can be converted to a Processor using the Type Converter mechanism, then this is used to process the message. The ActiveMQ component uses this mechanism to allow any JMS MessageListener to be invoked directly by Camel without having to write any integration glue code. You can use the same mechanism to integrate Camel into any other messaging/remoting frameworks.
- if the body of the message can be converted to a BeanInvocation (the default payload used by the ProxyHelper) component - then that is used to invoke the method and pass its arguments
- otherwise the type of the body is used to find a matching method; an error is thrown if a single method cannot be chosen unambiguously.
- you can also use Exchange as the parameter itself, but then the return type must be void.
- if the bean class is private (or package-private), interface methods will be preferred (from Camel 2.9 onwards) since Camel can't invoke class methods on such beans
In cases where Camel cannot choose a method to invoke, an AmbiguousMethodCallException
is thrown.
By default the return value is set on the outbound message body.
Parameter binding
When a method has been chosen for invocation, Camel will bind to the parameters of the method.
The following Camel-specific types are automatically bound:
org.apache.camel.Exchange
org.apache.camel.Message
org.apache.camel.CamelContext
org.apache.camel.TypeConverter
org.apache.camel.spi.Registry
java.lang.Exception
So, if you declare any of these types, they will be provided by Camel. Note that Exception
will bind to the caught exception of the Exchange - so it's often usable if you employ a Pojo to handle, e.g., an onException
route.
What is most interesting is that Camel will also try to bind the body of the Exchange to the first parameter of the method signature (albeit not of any of the types above). So if, for instance, we declare a parameter as String body
, then Camel will bind the IN body to this type. Camel will also automatically convert to the type declared in the method signature.
Let's review some examples:
Below is a simple method with a body binding. Camel will bind the IN body to the body
parameter and convert it to a String
.
public String doSomething(String body)
|
In the following sample we got one of the automatically-bound types as well - for instance, a Registry
that we can use to lookup beans.
public String doSomething(String body, Registry registry)
|
We can use Exchange as well:
public String doSomething(String body, Exchange exchange)
|
You can also have multiple types:
public String doSomething(String body, Exchange exchange, TypeConverter converter)
|
And imagine you use a Pojo to handle a given custom exception InvalidOrderException
- we can then bind that as well:
public String badOrder(String body, InvalidOrderException invalid)
|
Notice that we can bind to it even if we use a sub type of java.lang.Exception
as Camel still knows it's an exception and can bind the cause (if any exists).
So what about headers and other stuff? Well now it gets a bit tricky - so we can use annotations to help us, or specify the binding in the method name option.
See the following sections for more detail.
Binding Annotations
You can use the Parameter Binding Annotations to customize how parameter values are created from the Message
Examples
For example, a Bean such as:
public class Bar {
public String doSomething(String body) {
// process the in body and return whatever you want
return "Bye World";
}
|
Or the Exchange example. Notice that the return type must be void when there is only a single parameter of the type org.apache.camel.Exchange
:
public class Bar {
public void doSomething(Exchange exchange) {
// process the exchange
exchange.getIn().setBody("Bye World");
}
|
@Handler
You can mark a method in your bean with the @Handler annotation to indicate that this method should be used for Bean Binding.
This has an advantage as you need not specify a method name in the Camel route, and therefore do not run into problems after renaming the method in an IDE that can't find all its references.
public class Bar {
@Handler
public String doSomething(String body) {
// process the in body and return whatever you want
return "Bye World";
}
|
Parameter binding using method option
Available as of Camel 2.9
Camel uses the following rules to determine if it's a parameter value in the method option
- The value is either
true
orfalse
which denotes a boolean value - The value is a numeric value such as
123
or7
- The value is a String enclosed with either single or double quotes
- The value is null which denotes a
null
value - It can be evaluated using the Simple language, which means you can use, e.g., body, header.foo and other Simple tokens. Notice the tokens must be enclosed with ${ }.
Any other value is consider to be a type declaration instead - see the next section about specifying types for overloaded methods.
When invoking a Bean you can instruct Camel to invoke a specific method by providing the method name:
.bean(OrderService. class , "doSomething")
|
Here we tell Camel to invoke the doSomething method - Camel handles the parameters' binding. Now suppose the method has 2 parameters, and the 2nd parameter is a boolean where we want to pass in a true value:
public void doSomething(String payload, boolean highPriority) {
...
} |
This is now possible in Camel 2.9 onwards:
.bean(OrderService. class , "doSomething(*, true )")
|
In the example above, we defined the first parameter using the wild card symbol *, which tells Camel to bind this parameter to any type, and let Camel figure this out. The 2nd parameter has a fixed value of true
. Instead of the wildcard symbol we can instruct Camel to use the message body as shown:
.bean(OrderService. class , "doSomething(${body}, true )")
|
The syntax of the parameters is using the Simple expression language so we have to use ${ } placeholders in the body to refer to the message body.
If you want to pass in a null
value, then you can explicit define this in the method option as shown below:
.to("bean:orderService?method=doSomething( null , true )")
|
Specifying null
as a parameter value instructs Camel to force passing a null
value.
Besides the message body, you can pass in the message headers as a java.util.Map
:
.bean(OrderService. class , "doSomethingWithHeaders(${body}, ${headers})")
|
You can also pass in other fixed values besides booleans. For example, you can pass in a String and an integer:
.bean(MyBean. class , "echo(&# 39 ;World&# 39 ;, 5 )")
|
In the example above, we invoke the echo method with two parameters. The first has the content 'World' (without quotes), and the 2nd has the value of 5.
Camel will automatically convert these values to the parameters' types.
Having the power of the Simple language allows us to bind to message headers and other values such as:
.bean(OrderService. class , "doSomething(${body}, ${header.high})")
|
You can also use the OGNL support of the Simple expression language. Now suppose the message body is an object which has a method named asXml
. To invoke the asXml
method we can do as follows:
.bean(OrderService. class , "doSomething(${body.asXml}, ${header.high})")
|
Instead of using .bean
as shown in the examples above, you may want to use .to
instead as shown:
.to("bean:orderService?method=doSomething(${body.asXml}, ${header.high})") |
Using type qualifiers to select among overloaded methods
Available as of Camel 2.8
If you have a Bean with overloaded methods, you can now specify parameter types in the method name so Camel can match the method you intend to use.
Given the following bean:
public static final class MyBean {
public String hello(String name) {
return "Hello " + name;
}
public String hello(String name, @Header ("country") String country) {
return "Hello " + name + " you are from " + country;
}
public String times(String name, @Header ("times") int times) {
StringBuilder sb = new StringBuilder();
for ( int i = 0 ; i < times; i++) {
sb.append(name);
}
return sb.toString();
}
public String times( byte [] data, @Header ("times") int times) {
String s = new String(data);
StringBuilder sb = new StringBuilder();
for ( int i = 0 ; i < times; i++) {
sb.append(s);
if (i < times - 1 ) {
sb.append(",");
}
}
return sb.toString();
}
public String times(String name, int times, char separator) {
StringBuilder sb = new StringBuilder();
for ( int i = 0 ; i < times; i++) {
sb.append(name);
if (i < times - 1 ) {
sb.append(separator);
}
}
return sb.toString();
}
} |
Then the MyBean
has 2 overloaded methods with the names hello
and times
. So if we want to use the method which has 2 parameters we can do as follows in the Camel route:
from("direct:start") .bean(MyBean. class , "hello(String,String)")
.to("mock:result");
|
We can also use a *
as wildcard so we can just say we want to execute the method with 2 parameters we do
from("direct:start") .bean(MyBean. class , "hello(*,*)")
.to("mock:result");
|
By default Camel will match the type name using the simple name, e.g. any leading package name will be disregarded. However if you want to match using the FQN, then specify the FQN type and Camel will leverage that. So if you have a com.foo.MyOrder
and you want to match against the FQN, and not the simple name "MyOrder", then follow this example:
.bean(OrderService. class , "doSomething(com.foo.MyOrder)")
|
Camel currently only supports either specifying parameter binding or type per parameter in the method name option. You cannot specify both at the same time, such as
doSomething(com.foo.MyOrder ${body}, boolean ${header.high})
|
This may change in the future.
相关推荐
通过这种领域定义语言,你可以在你的IDE中用简单的Java Code就可以写出一个类型安全并具有一定智能的规则描述文件。这与那种复杂的XML配置相比极大简化了规则定义开发。 当然Apache Camel也提供了一个对Spring 配置...
如:jetty、file、activemq、ftp、http、log、并行、分支、发送邮件、接收邮件、seda队列、timer定时器、netty4、quartz2定时器、zookeeper操作,只是简单案例,方便学习, 适合入门和研究camel。不喜勿喷...
Camel示例说明 searches and publish results in real time using web socket to a web page.
弹簧靴骆驼快速入门本示例演示了如何基于将Apache Camel与Spring Boot结合使用。 快速入门使用Spring Boot配置一个小的应用程序,该应用程序包含一个骆驼路由,该路由每5秒触发一次消息,并将消息路由到日志。 该...
以下的例子说明了EndpointDirect的简单使用方式。以上代码片段中,我们编排了两个可用的路由(尽管两个路由都很简单,但确实是两个独立的路由)命名为DirectRouteA和DirectRouteB。其中DirectRouteA实例在最后一个...
# 生产者模板 # APACHE CAMEL SPRING BOOT启动器 #CAMEL SPRING BOOT 启动器 #简单表达语法 资源为翻译后根据camel书讲其中大多数语法替换为专业语法。准确度很高,欢迎下载
通过这种领域定义语言,你可以在你的IDE中用简单的JavaCode就可以写出一个类型安全并具有一定智能的规则描述文件。这与那种复杂的XML配置相比极大简化了规则定义开发。当然ApacheCamel也提供了一个对Spring配置文件...
#Camel Helloworld 保险丝在 jboss-fuse-6.1.0.redhat-379 上测试##部署(普通保险丝) 可以通过多种方式部署到普通保险丝(无织物)中: ###通过部署文件夹这假设您的容器上已经运行了骆驼功能cp target/camel-...
apache-camel-demo 这是Apache Camel的简单演示。如何使用 ? 在CamelDemo类中执行main方法之后,将处理input / text.txt文件。 一旦处理完文件,它就会移到.camel文件夹,但是代码仍会轮询新文件,因此您可以将更多...
Camel / CXF Gradle 示例这是一个使用 Apache Camel 和 Apache CXF 的 Hello World 项目公开了一个简单的 Web 服务 HelloService.wsdl。 构建并运行主类。 网址是 通过 SOAP-UI 进行测试。
使用 Apache Camel 和 Spring 集成的企业集成模式。 用于使用框架演示 EIP 的域是自行车商店。 自行车商店导入 CSV 交货单和订单。 ##Import of delivery notes 每条交货单记录都被转换成一个StockItem 并发送到eip....
骆驼彗星演示 一个简单的示例项目,演示了如何使用Apache Camel接收JMS,然后将消息发布到CometD通道,然后由Web浏览器将其拾取。在网上在DZone Javalobby上精选 在我的博客上先决条件您需要安装和配置Java(JDK)和...
简单语言的实时验证(红色下划线错误) 过滤后的端点选项仅在用作消费者与生产者模式时仅包含适用的选项 通过单击装订线中的 Camel 图标快速导航到路由到此路线的其他 Camel 路线 打算添加新的 Camel 端点( alt + ...
它显示了如何处理骆驼错误并将其传递给BPMS,以使用连接器进行复杂事件处理和人工任务创建。 您可以阅读更详细的博客文章,其中包含有关此演示的说明 ####支持的操作要查看组件支持的操作的完整列表,请查看官方的...
描述这是一个简单的项目,它演示了如何为特定存储过程配置 Spring bean 并参与 Apache Camel 路由。设置和安装设置环境和运行此演示的步骤: 查找可用的 Oracle 数据库环境,或安装 Oracle XE 11g。 转至下载它及其...
Camel Router WAR 项目 - 使用一点点 Docker 该项目包括一个作为 WAR 的示例路由。 还有一些额外的码头工人的东西。 您可以通过运行来构建 WAR mvn install 然后,您可以通过将 WAR 放入您喜欢的 Web 容器中来...
webshop-camel-springmvc 一个展示如何在控制器中集成 Camel 路由的项目。 用例是一个简单的网上商店,有几个产品和 2 个配送中心。 我们想通过 Camel DSL 管理控制器背后的逻辑。 使用 hawtio 监控路由 ( )
概述这是一个自定义 Camel/CDI 示例,用于使用 Fabric8 v2、OpenShift 和 Jenkins 测试部署管道用法构建项目mvn install 设置 OpenShift 实例,请参阅通过 Jenkins UI 触发构建作业(找到“服务”的端点) 这项工作...
Quarkus +骆驼+单元测试 该项目使用Quarkus(超音速亚原子Java...当前项目中的唯一测试是使用JUnit4和Camel Test工具运行的。 这利用了CamelTestSupport类,并将“模拟”端点注入到RouteBuilder ./mvnw clean verify