Camel入门经验
1、1. <beans profile="receiver">
Spring 3.1的功能,以后就不用为了区分Test, Dev, Production环境,搞几个只有细微区别的application.xml, application-test.xml及引用它们的web.xml了。 首先,将applicationContext.xml中的namespace从3.0升级到3.1.xsd, 然后就可以在文件末尾加入不同环境的定义,比如不同的dataSource
Xml代码
<beans profile="test">
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
</jdbc:embedded-database>
</beans>
<beans profile="production">
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
</beans>
2.在web.xml里,你需要定义使用的profile,最聪明的做法是定义成context-param,注意这里定义的是default值,在非生产环境,可以用系统变量"spring.profiles.active"进行覆盖。
Xml代码
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>production</param-value>
</context-param>
如果需要在eclipse设置development环境,在
Run As --》Run Configurations... --》Environment 设置变量:
spring.profiles.active = development
3.在其他地方进行覆盖 3.1 在development和functional test启动Jetty前设置系统变量
Java代码
System.setProperty("spring.profiles.active", "development");
server.start()
3.2 在用到ApplicationContext的单元测试用例中,用 @ActiveProfiles定义
Java代码
@ContextConfiguration(locations = { "/applicationContext.xml" })
@ActiveProfiles("test")
public class AccountDaoTest extends SpringTxTestCase {
}
演示了production,development,test,functional三个环境, 大家可以根据实际情况组合自己的环境管理。另外可以与Spring的properties文件加载时可顺位覆盖的特性(放一些不在版本管理中的xx.local.properties文件),更好的支持本地开发环境。
2、2. <camel:dataFormats>
<camel:dataFormats>
<jaxbid="prov"encoding="UTF-8"contextPath="com.aspire.edu.ebdc.schema.boss.header"/>
<camel:cryptoid="des"algorithm="DES/ECB/PKCS5Padding" keyRef="desKey"macAlgorithm="HmacSHA1"shouldAppendHMAC="true"/>
<camel:base64 id="base64" urlSafe="true"/>
</camel:dataFormats>
Camel supports a pluggable DataFormat to allow messages to be marshalled to and from binary or text formats to support a kind of Message Translator.
Camel支持可插入DataFormat允许消息打包和从二进制或文本格式转换为camel支持的一种消息翻译。
The following data formats are currently supported:
使用Spring XML
This example shows how to configure the data type just once and reuse it on multiple routes
这个例子展示了如何配置数据类型只有一次和重用它在多个路由
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<dataFormats>
<jaxb id="myJaxb" prettyPrint="true" contextPath="org.apache.camel.example"/>
</dataFormats>
<route>
<from uri="direct:start"/>
<marshal ref="myJaxb"/>
<to uri="direct:marshalled"/>
</route>
<route>
<from uri="direct:marshalled"/>
<unmarshal ref="myJaxb"/>
<to uri="mock:result"/>
</route>
</camelContext>
3、3. Route 一个route就是将一个输入队列中获得的消息,通过一步一步地设置好的逻辑判断(例如过滤器和路由规则)到达一个目标队列中(如果有的话)。Camel为应用开发者提供了两种途径来定义这些路由规则。一个是通过XML来定义路由信息,有关这部分的内容不会在本文档中讨论。另一种方式就是通过Camel所谓的Java DSL(domain-specific language) 来定义。 Introduction to Java DSL 对于许多人来说,要实现一个“domain-specific language” (面向领域的语言)涉及到了一个能够处理这个特定领域语言的关键字以及语法的编译器或者是解释器。对于Camel来说,它没有这么做。在Camel文档中一直都在使用的“Java DSL”而不是 “DSL” ,其目的就是想避免混淆这两个概念。Camel中的“Java DSL”是一个可以像DSL一样被使用的类库,除此之外它还使用了大量Java的语义。你可以看一下下面的例子,在例子下面的备注里, 解释了这个例子的中所用的组件。 Example of Camel's "Java DSL" RouteBuilder builder = new RouteBuilder() { public void configure() { from("queue:a").filter(header("foo").isEqualTo("bar")).to("queue:b"); from("queue:c").choice() .when(header("foo").isEqualTo("bar")).to("queue:d") .when(header("foo").isEqualTo("cheese")).to("queue:e") .otherwise().to("queue:f"); } }; CamelContext myCamelContext = new DefaultCamelContext(); myCamelContext.addRoutes(builder); 上面例子的第一行创建一个一个RouteBuilder的匿名类的实例,这个匿名类需要实现 configure()方法。 camelContext.addRoutes(RouterBuilder builder) 方法中调用了builder.setContext(this)方法,这样RouteBuilder对象就获得了与之对应的CamelContext的,然后调用builder.configure()方法。在configure方法中,可以调用例如 from(), filter(), choice(), when(),isEqualTo(), otherwise()以及to() 方法。 RouteBuilder.from(String uri) 方法会调用与之对应的CamelContext的getEndpoint(uri)方法来获得指定的Endpoint,并用一个FromBuilder包装这个Endpoint。这样 FromBuilder.filter(Predicate predicate) 方法就会创建一个在header("foo").isEqualTo("bar")这个表达式基础创建的Predicate(所谓的条件)创建一个FilterProcessor对象。就这样, 通过定义这些操作我们逐渐构建出了一个Route对象(使用RouterBuilder进行包装的)并且将这个Route对象添加进了与RouteBuilder所关联的CamelContext中。 Critique of Java DSL 在camel的在线文档中比较了Java DSL与建立在XML基础上的Spring配置文件的在配置routes和endpoint方法优势。特别是Java DSL比 XML 来说要精简很多。还有需要指出的是,现在很多集成开发环境都提供了一个自动补全的功能, 当然这种功能可以编写Java DSL的过程中使用,这也可以大大降低开发者编写Java DSL的难度。 当然在Camel的文档中还忽略了一些内容,就是通过一个解析器来处理存放在外部的DSL。当前Camel并没有提供这也的解析器,并且我也不知道Camel的开发维护人员是否打算做这样一个解析器。我像这个DSL解析器应该提供一个比当前Java DSL更大的一个好处。这个DSL可以通过巴柯斯范式来定义语法,这样Camel的用户可以通过阅读巴柯斯范式来获取书写DSL的知识,而不是像现在需要花费大量的时间通过阅读RouterBuilder类的API来获取。
4、4. Using handled with Spring DSL----
http://camel.apache.org/exception-clause.html
The same route as above in Spring DSL:
<!-- setup our error handler as the deal letter channel设置我们的错误处理程作为交易的信息通道-->
<bean id="errorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder">
<property name="deadLetterUri" value="mock:error"/>
</bean>
<!-- this is our POJO bean with our business logic defined as a plain spring bean
这是我们的POJO bean与我们的业务逻辑定义为一个简单的spring bean -->
<bean id="orderService" class="org.apache.camel.spring.processor.onexception.OrderService" />
<!-- this is the camel context where we define the routes -->
<!-- define our error handler as a global error handler -->
<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/spring">
<onException>
<!-- the exception is full qualified names as plain strings唯一的例外是全限定名作为普通字符串-->
<!-- there can be more just add a 2nd, 3rd exception element (unbounded) 可以有更多只需添加第二个,第三个例外元素(无限) -->
<exception>org.apache.camel.spring.processor.onexception.OrderFailedException</exception>
<!-- we can set the redelivery policy here as well我们也可以在这里设置交还政策-->
<redeliveryPolicy maximumRedeliveries="1" />
<!-- mark this as handled -->
<handled>
<constant>true</constant>
</handled>
<!-- let our order service handle this exception, call the orderFailed method -->
<bean ref="orderService" method="orderFailed" />
<!-- and since this is a unit test we use mock for assertions -->
<to uri="mock:error" />
</onException>
<route>
<!-- the route -->
<from uri="direct:start" />
<!-- in the normal route then route to our order service and call handleOrder method -->
<bean ref="orderService" method="handleOrder" />
<!-- and since this is a unit test we use mock for assertions -->
<to uri="mock:result" />
</route>
</camelContext>
5、5.Simper与Split
http://camel.apache.org/simple
http://camel.apache.org/splitter.html
<camel:when><!-- header 输入的标题 -->
<camel:simple>${body.bizPointList}</camel:simple>
<!-- 提取point -->
<camel:split parallelProcessing="true"><!-- 分流器 :The Splitter from the EIP patterns allows you split a message into a number of pieces and process them individuallyEIP模式的分流器允许您将消息分解成许多块,分别处理它们,parallelProcessing:并行处理-->
<camel:simple>${body.bizPointList.bizPoint}
</camel:simple>
<camel:setHeader headerName="point_cod">
<camel:simple>${body.pointCode}</camel:simple>
</camel:setHeader>
<camel:setHeader headerName="point_name">
<camel:simple>${body.pointName}</camel:simple>
</camel:setHeader>
<!-- 持久化point数据 -->
<camel:touri="sql:{{sql.insert.bossureg.point}}?dataSource=ebdc_ds"/>
</camel:split>
</camel:when>
<!-- 提取xml报文到camel body (body为输入的本体) -->
<camel:transform>
<camel:simple>${header.$xmldata}</camel:simple>
</camel:transform>
<!-- 解析xml报文prov,将解析结果字段提取到camel header -->
<camel:unmarshal ref="prov"/>
<camel:setHeader headerName="ProvBOSS">
<camel:simple>${body}</camel:simple>
</camel:setHeader>
<camel:setHeader headerName="BIPCode">
<camel:simple>${body.bIPCode}</camel:simple>
</camel:setHeader>
6、6. HTTP 参数 bean配置 http://camel.apache.org/http
<!-- Http params bean configuration -->
<bean id="http" class="org.apache.camel.component.http.HttpComponent">
<property name="camelContext" ref="receiver"/><!-- camel、receiver、pusher具体的要与web.xml相配 -->
<property name="httpConnectionManager" ref="myHttpConnectionManager"/>
</bean>
<bean id="myHttpConnectionManager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
<propertyname="params"ref="myHttpConnectionManagerParams"/>
</bean>
<bean id="myHttpConnectionManagerParams" class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">
<property name="connectionTimeout" value="60000"/>
<!--设置请求超时6秒钟 根据业务调整 -->
<property name="soTimeout" value="60000"/>
<!--设置等待数据超时时间6秒钟 根据业务调整 -->
</bean>
<!-- /Http params bean configuration -->