2.6. メッセージコンテンツの変換
概要
Apache Camel は、メッセージコンテンツを変換するためのさまざまなアプローチをサポートしています。Apache Camel は、メッセージコンテンツを変更するためのシンプルなネイティブ API に加えて、いくつかの異なるサードパーティーライブラリーや変換のための標準とのインテグレーションをサポートしています。
2.6.1. シンプルなメッセージ変換
概要
Java DSL にはビルトインの API があり、送受信メッセージのシンプルな変換を実行できます。たとえば、例2.1「受信メッセージのシンプルな変換」 に示すルールは、受信メッセージのボディー部の末尾にテキスト World!
を追加します。
例2.1 受信メッセージのシンプルな変換
from("SourceURL").setBody(body().append(" World!")).to("TargetURL");
ここで、setBody()
コマンドは受信メッセージボディーのコンテンツを置き換えます。
シンプルな変換の API
以下の API クラスを使用して、ルーターのルールによってメッセージコンテンツのシンプルな変換を実行できます。
-
org.apache.camel.model.ProcessorDefinition
-
org.apache.camel.builder.Builder
-
org.apache.camel.builder.ValueBuilder
ProcessorDefinition クラス
org.apache.camel.model.ProcessorDefinition
クラスは、ルーターのルールに直接挿入できる DSL コマンドを定義しています (例: 例2.1「受信メッセージのシンプルな変換」 の setBody()
コマンド)。表2.5「ProcessorDefinition クラスの変換メソッド」 は、メッセージコンテンツの変換に関係のある ProcessorDefinition
のメソッドを示しています。
メソッド | 説明 |
---|---|
| IN メッセージのボディーを指定の型に変換します。 |
| FAULT メッセージのヘッダーを削除するプロセッサーを追加します。 |
| IN メッセージ上のヘッダーを削除するプロセッサーを追加します。 |
| エクスチェンジプロパティーを削除するプロセッサーを追加します。 |
| IN メッセージのボディーをセットするプロセッサーを追加します。 |
| FAULT メッセージのボディーをセットするプロセッサーを追加します。 |
| FAULT メッセージにヘッダーをセットするプロセッサーを追加します。 |
| IN メッセージにヘッダーをセットするプロセッサーを追加します。 |
| IN メッセージにヘッダーをセットするプロセッサーを追加します。 |
| OUT メッセージにヘッダーをセットするプロセッサーを追加します。 |
| OUT メッセージにヘッダーをセットするプロセッサーを追加します。 |
| エクスチェンジプロパティーをセットするプロセッサーを追加します。 |
| エクスチェンジプロパティーをセットするプロセッサーを追加します。 |
| OUT メッセージのボディーをセットするプロセッサーを追加します。 |
| OUT メッセージのボディーをセットするプロセッサーを追加します。 |
Builder クラス
org.apache.camel.builder.Builder
クラスは、式または述語が想定される文脈でのメッセージコンテンツへのアクセスを提供します。つまり、Builder
のメソッドは通常 DSL コマンドの 引数 の中で呼び出されます (例: 例2.1「受信メッセージのシンプルな変換」 の body()
コマンド)。表2.6「Builder クラスのメソッド」 では、Builder
クラスで利用可能な static メソッドをまとめています。
メソッド | 説明 |
---|---|
| エクスチェンジのインバウンドボディーに対する述語および値ビルダーを返します。 |
| インバウンドメッセージのボディーを特定の型として、それに対する述語および値ビルダーを返します。 |
| 定数式を返します。 |
| エクスチェンジのフォールトボディーに対する述語および値ビルダーを返します。 |
| フォールトメッセージのボディーを特定の型として、それに対する述語および値ビルダーを返します。 |
| エクスチェンジのヘッダーに対する述語および値ビルダーを返します。 |
| エクスチェンジのアウトバウンドボディーに対する述語および値ビルダーを返します。 |
| アウトバウンドメッセージのボディーを特定の型として、それに対する述語および値ビルダーを返します。 |
| エクスチェンジのプロパティーに対する述語および値ビルダーを返します。 |
| 正規表現のすべての出現箇所を、指定した置換文字列で置き換える式を返します。 |
| 正規表現のすべての出現箇所を、指定した置換文字列で置き換える式を返します。 |
| 指定したエンドポイント URI にエクスチェンジを送信する式を返します。 |
| 指定のシステムプロパティーの式を返します。 |
| 指定のシステムプロパティーの式を返します。 |
ValueBuilder クラス
org.apache.camel.builder.ValueBuilder
クラスを使用すると、Builder
メソッドによって返される値を変更できます。つまり、 ValueBuilder
のメソッドは、メッセージコンテンツを変更するシンプルな方法を提供します。表2.7「ValueBuilder クラスの変更メソッド」 では、ValueBuilder
クラスで利用可能なメソッドをまとめています。この表では、呼び出された値を変更するために使用されるメソッドのみが示されています (詳細は API Reference ドキュメントを参照してください) 。
メソッド | 説明 |
---|---|
| 指定された値をこの式の文字列評価に追加します。 |
| 左辺の式に右辺の式の値が含まれた述語を作成します。 |
| 登録された型コンバーターを使用して、現在の値を指定の型に変換します。 |
| 登録された型コンバーターを使用して、現在の値を String に変換します。 |
| |
| |
| |
| |
|
現在の値が指定の |
|
現在の値が指定の |
|
現在の値が指定の |
| 現在の値が指定の型のインスタンスである場合、true を返します。 |
|
現在の値が指定の |
|
現在の値が指定の |
|
現在の値が指定の |
|
現在の値が |
|
現在の値が |
| |
| 述語の引数を否定にします。 |
| この式の文字列評価を指定された値に追加します。 |
| |
| 正規表現のすべての出現箇所を、指定した置換文字列で置き換えます。 |
| 正規表現のすべての出現箇所を、指定した置換文字列で置き換えます。 |
| 指定の正規表現を使用してこの式の文字列変換をトークン化します。 |
| 指定されたコンパレーターを使用して現在の値をソートします。 |
|
現在の値が |
| コンマのトークン区切り文字を使用してこの式の文字列変換をトークン化します。 |
| 指定のトークン区切り文字を使用してこの式の文字列変換をトークン化します。 |
2.6.2. マーシャリングとアンマーシャリング
Java DSL コマンド
以下のコマンドを使用して、低レベルのメッセージ形式と高レベルのメッセージ形式の間で変換を行うことができます。
-
marshal()
- 高レベルのデータフォーマットを低レベルのデータフォーマットに変換します。 -
unmarshal()
- 低レベルのデータフォーマットを高レベルのデータフォーマットに変換します。
データ形式
Apache Camel は、以下のデータフォーマットのマーシャリングおよびアンマーシャリングをサポートします。
- Java シリアライゼーション
- JAXB
- XMLBeans
- XStream
Java シリアライゼーション
Java オブジェクトをバイナリーデータの Blob に変換できるようにします。このデータフォーマットでは、アンマーシャリングはバイナリー Blob を Java オブジェクトに変換し、マーシャリングは Java オブジェクトをバイナリー Blob に変換します。たとえば、エンドポイント SourceURL からシリアライズされた Java オブジェクトを読み込み、これを Java オブジェクトに変換するには、以下のようなルールを使用します。
from("SourceURL").unmarshal().serialization() .<FurtherProcessing>.to("TargetURL");
または、Spring XML では以下の通りです。
<camelContext id="serialization" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="SourceURL"/> <unmarshal> <serialization/> </unmarshal> <to uri="TargetURL"/> </route> </camelContext>
JAXB
XML スキーマ型と Java 型間のマッピングを提供します (https://jaxb.dev.java.net/ を参照してください)。JAXB では、アンマーシャリングは XML データ型を Java オブジェクトに変換し、マーシャリングは Java オブジェクトを XML データ型に変換します。JAXB データフォーマットを使用する前に、JAXB コンパイラーを使用して XML スキーマをコンパイルし、スキーマの XML データ型を表す Java クラスを生成する必要があります。これはスキーマの バインディング と呼ばれます。スキーマをバインドした後に、以下のようなコードを使用して XML データを Java オブジェクトにアンマーシャリングするルールを定義します。
org.apache.camel.spi.DataFormat jaxb = new org.apache.camel.converter.jaxb.JaxbDataFormat("GeneratedPackageName"); from("SourceURL").unmarshal(jaxb) .<FurtherProcessing>.to("TargetURL");
GeneratedPackagename は JAXB コンパイラーによって生成された Java パッケージの名前で、XML スキーマを表す Java クラスが含まれます。
または、Spring XML では以下の通りです。
<camelContext id="jaxb" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="SourceURL"/> <unmarshal> <jaxb prettyPrint="true" contextPath="GeneratedPackageName"/> </unmarshal> <to uri="TargetURL"/> </route> </camelContext>
XMLBeans
XML スキーマ型と Java 型間の代替的なマッピングを提供します (http://xmlbeans.apache.org/ を参照してください) 。XMLBean では、アンマーシャリングは XML データ型を Java オブジェクトに変換し、マーシャリングは Java オブジェクトを XML データ型に変換します。たとえば、XMLBean を使用して XML データを Java オブジェクトにアンマーシャリングするには、以下のようなコードを使用します。
from("SourceURL").unmarshal().xmlBeans() .<FurtherProcessing>.to("TargetURL");
または、Spring XML では以下の通りです。
<camelContext id="xmlBeans" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="SourceURL"/> <unmarshal> <xmlBeans prettyPrint="true"/> </unmarshal> <to uri="TargetURL"/> </route> </camelContext>
XStream
XML 型と Java 型間のもう 1 つのマッピングを提供します (http://www.xml.com/pub/a/2004/08/18/xstream.html を参照してください) 。XStream はシリアライゼーションライブラリー (Java シリアライゼーションなど) で、Java オブジェクトを XML に変換できるものです。XStream では、アンマーシャリングは XML データ型を Java オブジェクトに変換し、マーシャリングは Java オブジェクトを XML データ型に変換します。
from("SourceURL").unmarshal().xstream() .<FurtherProcessing>.to("TargetURL");
XStream データフォーマットは現在 Spring XML ではサポート されません。
2.6.3. エンドポイントバインディング
バインディングの概要
Apache Camel において、バインディング とは、エンドポイントにコントラクトを結び付ける方法です。たとえば Data Format、Content Enricher、または検証ステップを適用することでコントラクトを結び付けます。入力メッセージには条件または変換が適用され、出力メッセージには補完的な条件または変換が適用されます。
DataFormatBinding
DataFormatBinding
クラスは、特定のデータフォーマットをマーシャリングしたりアンマーシャリングしたりするバインディングを定義する場合に有効です (「マーシャリングとアンマーシャリング」 を参照)。この場合、バインディングの作成に必要なのは、コンストラクターに必要なデータフォーマットへの参照を渡して DataFormatBinding
インスタンスを作成することだけです。
たとえば、例2.2「JAXB バインディング」 の XML DSL スニペットは、Apache Camel エンドポイントに関連付けられたときに、JAXB データフォーマットをマーシャリングおよびアンマーシャリングできるバインディング (ID は jaxb
) を示しています。
例2.2 JAXB バインディング
<beans ... >
...
<bean id="jaxb" class="org.apache.camel.processor.binding.DataFormatBinding">
<constructor-arg ref="jaxbformat"/>
</bean>
<bean id="jaxbformat" class="org.apache.camel.model.dataformat.JaxbDataFormat">
<property name="prettyPrint" value="true"/>
<property name="contextPath" value="org.apache.camel.example"/>
</bean>
</beans>
バインディングとエンドポイントの関連付け
エンドポイントとバインディングを関連付けるには、以下の方法を使用できます。
Binding URI
バインディングをエンドポイントに関連付けるには、エンドポイント URI に binding:NameOfBinding
を接頭辞として付けます。ここで NameOfBinding
は、バインディングの Bean ID になります (例: Spring XML で作成されたバインディング Bean の ID)。
たとえば、以下の例では、ActiveMQ エンドポイントを 例2.2「JAXB バインディング」 で定義された JAXB バインディングに関連付ける方法を示しています。
<beans ...> ... <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="binding:jaxb:activemq:orderQueue"/> <to uri="binding:jaxb:activemq:otherQueue"/> </route> </camelContext> ... </beans>
BindingComponent
接頭辞を使用してバインディングをエンドポイントに関連付ける代わりに、関連付けを暗黙的に行い、バインディングが URI に表示されないようにすることもできます。暗黙的なバインディングを持たない既存のエンドポイントの場合、最も簡単な方法は BindingComponent
クラスを使用してエンドポイントをラップすることです。
たとえば、jaxb
バインディングを activemq
エンドポイントに関連付けるには、以下のように新しい BindingComponent
インスタンスを定義します。
<beans ... >
...
<bean id="jaxbmq" class="org.apache.camel.component.binding.BindingComponent">
<constructor-arg ref="jaxb"/>
<constructor-arg value="activemq:foo."/>
</bean>
<bean id="jaxb" class="org.apache.camel.processor.binding.DataFormatBinding">
<constructor-arg ref="jaxbformat"/>
</bean>
<bean id="jaxbformat" class="org.apache.camel.model.dataformat.JaxbDataFormat">
<property name="prettyPrint" value="true"/>
<property name="contextPath" value="org.apache.camel.example"/>
</bean>
</beans>
jaxbmq
の 2 つ目のコンストラクター引数 (オプション) で URI 接頭辞を定義します。これで、この jaxbmq
ID をエンドポイント URI のスキームとして使用できるようになりました。たとえば、このバインディングコンポーネントを使用して以下のルートを定義できます。
<beans ...> ... <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="jaxbmq:firstQueue"/> <to uri="jaxbmq:otherQueue"/> </route> </camelContext> ... </beans>
上記のルートは、Binding URI のアプローチを使用する以下のルートと同じです。
<beans ...> ... <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="binding:jaxb:activemq:foo.firstQueue"/> <to uri="binding:jaxb:activemq:foo.otherQueue"/> </route> </camelContext> ... </beans>
カスタムの Apache Camel コンポーネントを実装する開発者は、org.apache.camel.spi.HasBinding
インターフェイスを継承するエンドポイントクラスを実装することで、これを実現できます。
BindingComponent コンストラクター
BindingComponent
クラスは以下のコンストラクターをサポートします。
public BindingComponent()
- 無引数の形式です。プロパティー注入を使用してバインディングコンポーネントインスタンスを設定します。
public BindingComponent(Binding binding)
-
このバインディングコンポーネントを指定された
Binding
オブジェクトのbinding
に関連付けます。 public BindingComponent(Binding binding, String uriPrefix)
-
このバインディングコンポーネントを指定された
Binding
オブジェクトのbinding
、および URI 接頭辞uriPrefix
に関連付けます。これが、最も一般的に使用されるコンストラクターです。 public BindingComponent(Binding binding, String uriPrefix, String uriPostfix)
-
このコンストラクターは、追加の URI ポストフィックス
uriPostfix
引数をサポートします。これは、このバインディングコンポーネントを使用して定義された URI に自動的に追加されます。
カスタムバインディングの実装
マーシャリングおよびアンマーシャリングのデータフォーマットに使用される DataFormatBinding
に加えて、独自のカスタムバインディングを実装することができます。カスタムバインディングを以下のように定義します。
-
org.apache.camel.Processor
クラスを実装して、(from
要素に登場) コンシューマーエンドポイントで受信するメッセージに対して変換を行います。 -
補完関係となる
org.apache.camel.Processor
クラスを実装して、プロデューサーエンドポイント (to
要素に登場) から送信されるメッセージに対して逆変換を行います。 -
org.apache.camel.spi.Binding
インターフェイスを実装します。これは上記のプロセッサーインスタンスのファクトリーとして機能します。
Binding インターフェイス
例2.3「org.apache.camel.spi.Binding インターフェイス」 は org.apache.camel.spi.Binding
インターフェイスの定義を示しています。このインタフェースは、カスタムバインディングを定義するために実装する必要があります。
例2.3 org.apache.camel.spi.Binding インターフェイス
// Java package org.apache.camel.spi; import org.apache.camel.Processor; /** * Represents a <a href="http://camel.apache.org/binding.html">Binding</a> or contract * which can be applied to an Endpoint; such as ensuring that a particular * <a href="http://camel.apache.org/data-format.html">Data Format</a> is used on messages in and out of an endpoint. */ public interface Binding { /** * Returns a new {@link Processor} which is used by a producer on an endpoint to implement * the producer side binding before the message is sent to the underlying endpoint. */ Processor createProduceProcessor(); /** * Returns a new {@link Processor} which is used by a consumer on an endpoint to process the * message with the binding before its passed to the endpoint consumer producer. */ Processor createConsumeProcessor(); }
バインディングを使うタイミング
バインディングは、多くの異なるエンドポイントに同じ種類の変換を適用する必要がある場合に有効です。