4.3. Java オブジェクトとの間のマーシャリング
HTTP で送信するための Java オブジェクトのマーシャリング リンクのコピーリンクがクリップボードにコピーされました!
REST プロトコルを使用する最も一般的な方法の 1 つは、Java Bean の内容をメッセージボディーで送信することです。これを実現させるには、Java オブジェクトを適切なデータフォーマットとの間でマーシャリングするメカニズムが必要です。Java オブジェクトのエンコードに適した以下のデータフォーマットが REST DSL でサポートされています。
- JSON
JSON (JavaScript Object Notation) は、Java オブジェクトとの間で簡単にマッピングできる軽量なデータフォーマットです。JSON 構文はコンパクトで、緩く型指定され、人間が読み書きがしやすい構文です。これらの理由から、JSON は REST サービスのメッセージ形式として人気があります。
たとえば、以下の JSON コードは、
id
とname
の 2 つのプロパティーフィールドを持つUser
Bean を表現できます。{ "id" : 1234, "name" : "Jane Doe" }
{ "id" : 1234, "name" : "Jane Doe" }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - JAXB
JAXB(Java Architecture for XML Binding) は、Java オブジェクトと XML の間で簡単にマッピングできるデータフォーマットです。XML を Java オブジェクトにマーシャリングするには、使用する Java クラスにアノテーションを付ける必要があります。
たとえば、以下の JAXB コードは、
id
とname
の 2 つのプロパティーフィールドを持つUser
Bean を表現できます。<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <User> <Id>1234</Id> <Name>Jane Doe</Name> </User>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <User> <Id>1234</Id> <Name>Jane Doe</Name> </User>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注記Camel 2.17.0 以降、JAXB データフォーマットと型コンバーターは、
XmlRootElement
の代わりにObjectFactory
を使用するクラスの XML から POJO への変換をサポートします。また、Camel コンテキストでは、値が true のCamelJaxbObjectFactory
プロパティーを含める必要があります。ただし、後方互換のためにデフォルトは false になっています。
REST DSL による JSON と JAXB の統合 リンクのコピーリンクがクリップボードにコピーされました!
メッセージボディーを Java オブジェクトへ変換するために必要なコードを自分で書くこともできます。しかし、REST DSL は、この変換を自動的に実行する利便性を提供します。特に、JSON と JAXB を REST DSL と統合すると、以下のようなメリットがあります。
- Java オブジェクトとの間のマーシャリングは自動的に実行されます (適切な設定がある場合)。
- REST DSL は、データフォーマット (JSON または JAXB のいずれか) を自動的に検出し、適切な変換を行うことができます。
- REST DSL は 抽象化レイヤー を提供するので、開発するコードは JSON または JAXB 実装に固有のものではありません。そのため、アプリケーションコードへの影響を最小限に抑えながら、後から実装を切り替えることができます。
サポートされるデータフォーマットコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
Apache Camel は JSON と JAXB データフォーマットの多くの実装を提供しています。現在、REST DSL では以下のデータフォーマットがサポートされています。
JSON
-
Jackson データフォーマット (
camel-jackson
) (デフォルト) -
gson データフォーマット (
camel-gson
) -
XStream データフォーマット (
camel-xstream
)
-
Jackson データフォーマット (
JAXB
-
JAXB データフォーマット (
camel-jaxb
)
-
JAXB データフォーマット (
オブジェクトマーシャリングを有効にする方法 リンクのコピーリンクがクリップボードにコピーされました!
REST DSL でオブジェクトのマーシャリングを有効にする場合は、以下の点に注意してください。
-
bindingMode
オプションを設定してバインディングモードを有効にします (バインディングモードを設定できるレベルはいくつかあり、詳細は 「バインディングモードの設定」 を参照してください)。 -
受信メッセージでは
type
オプション (必須)、送信メッセージではoutType
オプション (任意) を使用して、変換先 (または変換元) の Java 型を指定します。 - Java オブジェクトを JAXB データフォーマットとの間で変換する場合、Java クラスに適切な JAXB アノテーションを付ける必要があります。
-
jsonDataFormat
オプションやxmlDataFormat
オプション (restConfiguration
ビルダーで指定可能) を使用して、ベースとなるデータフォーマットの実装を指定します。 ルートが JAXB 形式の戻り値を提供する場合、通常、エクスチェンジボディーの Out メッセージを JAXB アノテーションを持つクラスのインスタンス (JAXB 要素) に設定することが期待されます。ただし、JAXB の戻り値を XML 形式で直接提供する場合は、キー
xml.out.mustBeJAXBElement
でdataFormatProperty
をfalse
に設定します (restConfiguration
ビルダーで指定可能)。たとえば、XML DSL の構文では以下になります。<restConfiguration ...> <dataFormatProperty key="xml.out.mustBeJAXBElement" value="false"/> ... </restConfiguration>
<restConfiguration ...> <dataFormatProperty key="xml.out.mustBeJAXBElement" value="false"/> ... </restConfiguration>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 必要な依存関係をプロジェクトのビルドファイルに追加します。たとえば、Maven ビルドシステムを使用し、Jackson データフォーマットを使用している場合、次の依存関係を Maven POM ファイルに追加します。
Copy to Clipboard Copied! Toggle word wrap Toggle overflow アプリケーションを OSGi コンテナーにデプロイする際には、必ず選択したデータフォーマットに必要な機能をインストールしてください。たとえば、Jackson データフォーマット (デフォルト) を使用している場合、以下の Karaf コンソールコマンドを入力して
camel-jackson
機能をインストールします。JBossFuse:karaf@root> features:install camel-jackson
JBossFuse:karaf@root> features:install camel-jackson
Copy to Clipboard Copied! Toggle word wrap Toggle overflow また、Fabric 環境にデプロイする場合は、Fabric プロファイルにその機能を追加します。たとえば、プロファイル
MyRestProfile
を使用している場合は、次のコンソールコマンドを入力して機能を追加できます。JBossFuse:karaf@root> fabric:profile-edit --features camel-jackson MyRestProfile
JBossFuse:karaf@root> fabric:profile-edit --features camel-jackson MyRestProfile
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
バインディングモードの設定 リンクのコピーリンクがクリップボードにコピーされました!
bindingMode
オプションはデフォルトで off
になっているため、Java オブジェクトのマーシャリングを有効にするには、明示的に設定する必要があります。表は、サポートされているバインディングモードの一覧を示しています。
Camel 2.16.3 以降では、POJO から JSon/JAXB へのバインディングは、content-type ヘッダーに json または xml が含まれている場合にのみ発生します。これにより、カスタムのコンテンツタイプを指定することで、メッセージボディーがバインディングを使用してマーシャリングしなくなります。これは、メッセージボディーがカスタムバイナリーのペイロードである場合などに便利です。
バインディングモード | 説明 |
---|---|
| バインディングはオフになります (デフォルト)。 |
| バインディングは JSON または XML に対して有効になります。このモードでは、Camel は受信メッセージのフォーマットに基づいて JSON または XML (JAXB) を自動選択します。必ずしも両方のデータフォーマットの実装を有効にする必要はありません。JSON の実装と XML の実装のどちらかまたは両方をクラスパスで提供します。 |
|
バインディングは JSON でのみ有効になります。クラスパスに JSON の実装を用意 しなければなりません (デフォルトでは、Camel は |
|
バインディングは XML でのみ有効です。クラスパスに XML の実装を用意 しなければなりません (デフォルトでは、Camel は |
| バインディングは JSON と XML の両方に対して有効になります。このモードでは、Camel は受信メッセージのフォーマットに基づいて JSON または XML (JAXB) を自動選択します。クラスパスに 両方 のデータフォーマットの実装を用意する必要があります。 |
Java では、これらのバインディングモード値は、以下の enum
型のインスタンスとして表されます。
org.apache.camel.model.rest.RestBindingMode
org.apache.camel.model.rest.RestBindingMode
bindingMode
が設定できるレベルは、以下のように複数あります。
- REST DSL の設定
以下のように、
restConfiguration
ビルダーからbindingMode
オプションを設定できます。restConfiguration().component("servlet").port(8181).bindingMode(RestBindingMode.json);
restConfiguration().component("servlet").port(8181).bindingMode(RestBindingMode.json);
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - サービス定義のベースパート
rest()
キーワードの直後 (Verb 句の前) に、以下のようにbindingMode
オプションを設定することができます。rest("/user").bindingMode(RestBindingMode.json).get("/{id}").VerbClause
rest("/user").bindingMode(RestBindingMode.json).get("/{id}").VerbClause
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Verb 句
Verb 句で
bindingMode
オプションを設定する場合は、以下のようになります。rest("/user") .get("/{id}").bindingMode(RestBindingMode.json).to("...");
rest("/user") .get("/{id}").bindingMode(RestBindingMode.json).to("...");
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
例 リンクのコピーリンクがクリップボードにコピーされました!
Servlet コンポーネントを REST 実装として使用して、REST DSL を使用する方法を示す完全なコード例は、Apache Camel の camel-example-servlet-rest-blueprint
の例を参照してください。この例は、スタンドアロンの Apache Camel ディストリビューション apache-camel-2.23.2.fuse-790054-redhat-00001.zip
をインストールして見ることができます。これは、Fuse インストールの extras/
サブディレクトリーにあります。
スタンドアロン Apache Camel ディストリビューションのインストール後に、以下のディレクトリーでサンプルコードを確認できます。
ApacheCamelInstallDir/examples/camel-example-servlet-rest-blueprint
ApacheCamelInstallDir/examples/camel-example-servlet-rest-blueprint
REST 実装として Servlet コンポーネントを設定 リンクのコピーリンクがクリップボードにコピーされました!
camel-example-servlet-rest-blueprint
の例では、REST DSL のベースとなる実装は Servlet コンポーネントによって提供されます。Servlet コンポーネントは、例4.1「REST DSL の Servlet コンポーネントの設定」 に示されているように、Blueprint XML ファイルで設定されます。
例4.1 REST DSL の Servlet コンポーネントの設定
Servlet コンポーネントを REST DSL で設定するには、以下の 3 つのレイヤーを設定する必要があります。
- REST DSL レイヤー
-
REST DSL レイヤーは
restConfiguration
要素によって設定され、component
属性をservlet
という値に設定することで Servlet コンポーネントと統合されます。 - Servlet コンポーネントレイヤー
-
Servlet コンポーネントレイヤーは、クラス
CamelHttpTransportServlet
のインスタンスとして実装され、このサンプルインスタンスには Bean IDcamelServlet
があります。 - HTTP コンテナーレイヤー
Servlet コンポーネントは HTTP コンテナーにデプロイする必要があります。Karaf コンテナーには通常、ポート 8181 の HTTP リクエストをリッスンするデフォルトの HTTP コンテナー (Jetty HTTP コンテナー) が提供されています。Servlet コンポーネントをデフォルトの Jetty HTTP コンテナーにデプロイするには、以下を行います。
-
OSGi サービス (
org.osgi.service.http.HttpService
) への OSGi 参照を取得します。このサービスは、OSGi のデフォルト HTTP サーバーへのアクセスを提供する標準化された OSGi インターフェイスです。 -
ユーティリティークラスのインスタンス (
OsgiServletRegisterer
) を作成して、HTTP コンテナーに Servlet コンポーネントを登録します。OsgiServletRegisterer
クラスは、Servlet コンポーネントのライフサイクル管理を簡素化するユーティリティーです。このクラスのインスタンスが作成されると、HttpService
OSGi サービス上のregisterServlet
メソッドが自動的に呼び出され、インスタンスが破棄されると、unregister
メソッドが自動的に呼び出されます。
-
OSGi サービス (
必要な依存関係 リンクのコピーリンクがクリップボードにコピーされました!
この例には、REST DSL にとって重要な以下の 2 つの依存関係があります。
- Servlet コンポーネント
REST DSL のベースとなる実装を提供します。以下のように Maven POM ファイルで指定します。
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-servlet</artifactId> <version>${camel-version}</version> </dependency>
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-servlet</artifactId> <version>${camel-version}</version> </dependency>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow また、OSGi コンテナーにデプロイする場合、以下のように Servlet コンポーネント機能をインストールする必要があります。
JBossFuse:karaf@root> features:install camel-servlet
JBossFuse:karaf@root> features:install camel-servlet
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Jackson データフォーマット
JSON データフォーマットの実装を提供します。以下のように Maven POM ファイルで指定します。
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> <version>${camel-version}</version> </dependency>
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> <version>${camel-version}</version> </dependency>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow また、OSGi コンテナーにデプロイする場合、以下のように Jackson データフォーマット機能をインストールする必要があります。
JBossFuse:karaf@root> features:install camel-jackson
JBossFuse:karaf@root> features:install camel-jackson
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
レスポンス用 の Java 型 リンクのコピーリンクがクリップボードにコピーされました!
サンプルアプリケーションは、HTTP リクエストメッセージとレスポンスメッセージで User
型のオブジェクトを渡し合います。Java クラス User
は、例4.2「JSON レスポンス用ユーザークラス」 で示すように定義されます。
例4.2 JSON レスポンス用ユーザークラス
クラス User
は、JSON データ形式で比較的シンプルに表現されます。たとえば、JSON 形式で表現されたこのクラスのインスタンスは次のようになります。
{ "id" : 1234, "name" : "Jane Doe" }
{
"id" : 1234,
"name" : "Jane Doe"
}
JSON バインディングを使用した REST DSL の例 リンクのコピーリンクがクリップボードにコピーされました!
この例の REST DSL 設定と REST サービス定義を 例4.3「JSON バインディングでの REST DSL の例」 に示します。
例4.3 JSON バインディングでの REST DSL の例
REST オペレーション リンクのコピーリンクがクリップボードにコピーされました!
例4.3「JSON バインディングでの REST DSL の例」 からの REST サービスは、以下の REST オペレーションを定義します。
GET /camel-example-servlet-rest-blueprint/rest/user/{id}
-
{id}
で識別されたユーザーの詳細を取得します。HTTP レスポンスは JSON 形式で返されます。 PUT /camel-example-servlet-rest-blueprint/rest/user
-
新しいユーザーを作成します。ユーザーの詳細は PUT メッセージのボディーに含まれ、JSON 形式でエンコードされます (
User
オブジェクトタイプと一致するように)。 GET /camel-example-servlet-rest-blueprint/rest/user/findAll
- すべてのユーザーの詳細を取得します。HTTP レスポンスはユーザーの配列で、JSON 形式で返されます。
REST サービスを呼び出すための URL リンクのコピーリンクがクリップボードにコピーされました!
例4.3「JSON バインディングでの REST DSL の例」 から REST DSL の定義を調べることで、各 REST オペレーションを呼び出すのに必要な URL をまとめることができます。たとえば、指定した ID を持つユーザーの詳細を返す最初の REST オペレーションを呼び出す場合、URL は以下になります。
http://localhost:8181
-
restConfiguration
では、プロトコルのデフォルトはhttp
で、ポートは明示的に8181
に設定されます。 /camel-example-servlet-rest-blueprint/rest
-
restConfiguration
要素のcontextPath
属性によって指定されます。 /user
-
rest
要素のpath
属性によって指定されます。 /{id}
-
verb 要素
get
のuri
属性によって指定されます。
したがって、コマンドラインで以下のコマンドを入力することで、curl
ユーティリティーでこの REST 操作を呼び出すことができます。
curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/123
curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/123
同様に、残りの REST オペレーションは、以下のサンプルコマンドを入力することにより、curl
で呼び出すことができます。
curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/findAll curl -X PUT -d "{ \"id\": 666, \"name\": \"The devil\"}" -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user
curl -X GET -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user/findAll
curl -X PUT -d "{ \"id\": 666, \"name\": \"The devil\"}" -H "Accept: application/json" http://localhost:8181/camel-example-servlet-rest-blueprint/rest/user