この記事のモジュール: Integration Flow Helper
SAP CPI の Camel Simple 式:header、プロパティ、${…} の使い方を例で解説
SAP CPI での Camel Simple 式の仕組み:${header.x}、${property.x}、${in.body}、日付、Content Modifier の評価順序、Router の条件、そして何も返さなくなる典型的なミスを解説します。

SAP Cloud Integration(SAP CPI)の iFlow に出てくる動的な値は、ほぼすべて Apache Camel の Simple 式言語で書かれています。レシーバーのアドレスに入れる header、Content Modifier のプロパティ、ファイル名の日付、Router の条件などです。構文は ${…} と短いものの、気づかないうちに少しだけ間違えやすいのが難点です。
この記事では、毎日使う式、Content Modifier が式を評価する順序、header と exchange property の違い、そして式が黙って何も返さなくなる典型的なミスを説明します。
SAP CPI における Simple 式とは
SAP Integration Suite は各 iFlow を Apache Camel 上で実行します。ステップが実行されると、Camel は入力欄の中の ${…} をすべて、現在のメッセージの値に置き換えます。header、exchange property、ボディ、または現在日付のような組み込み関数の値です。式の前後のテキストはそのまま残るため、Order-${header.orderId}.xml は Order-4711.xml になります。
Simple 式は、Content Modifier のタイプ Expression の値とメッセージボディ、多くのレシーバーアダプターのアドレス欄とクエリ欄、タイプ Non-XML の Router と Filter の条件、さらにメールの件名や SFTP のファイル名などの欄に書けます。外部化パラメーターは見た目が似ていますが別物です。{{receiverHost}} は iFlow をデプロイするときに一度だけ置き換えられ、${…} はメッセージごとに評価されます。
毎日使う式
ほとんどの iFlow はいくつかの式でまかなえ、通常のテキストと自由に組み合わせられます。たとえば Content Modifier のボディでは、header、プロパティ、関数から XML ドキュメント全体を組み立てられます。
<Order>
<Id>${property.orderId}</Id>
<Customer>${header.customerId}</Customer>
<ReceivedOn>${date:now:yyyy-MM-dd}</ReceivedOn>
<Flow>${camelId}</Flow>
<MessageLog>${property.SAP_MessageProcessingLogID}</MessageLog>
</Order>| 式 | 返す値 |
|---|---|
${header.orderId} | メッセージ header の orderId |
${property.orderId} | exchange property の orderId(Camel は ${exchangeProperty.orderId} も受け付けます) |
${in.body} または ${body} | 現在のメッセージボディ(テキスト) |
${date:now:yyyy-MM-dd} | 指定した Java の日付パターンでの今日の日付 |
${camelId} | 実行中のインテグレーションフローの名前 |
${property.SAP_MessageProcessingLogID} | 現在のメッセージ処理ログの ID |
${header.CamelHttpResponseCode} | 直前の HTTP 呼び出しが返したステータスコード |
Content Modifier が header、プロパティ、ボディを評価する順序
Content Modifier はタブを決まった順序で処理します。まず Message Header テーブル、次に Exchange Property テーブル、最後に Message Body です。各テーブルの中では、行が上から下へ順に処理されます。
この順序によって、式から何が見えるかが決まります。プロパティの行は同じ Content Modifier で先に設定された header を読めますし、ボディはその両方を使えます。一方、header の行は同じ Content Modifier で設定されるプロパティを読めません。header を評価する時点ではそのプロパティがまだ存在しないため、空の値を読むことになります。必要なら、プロパティを手前の Content Modifier で設定するか、先に処理される header テーブルに値を移してください。
- ソースタイプ Expression:値は Simple 式です。例:
${date:now:yyyyMMdd}-${header.orderId}。 - ソースタイプ Header または Property:別の header やプロパティを名前でコピーします。名前を
${…}で囲む必要はありません。 - ソースタイプ XPath:XML のボディから値を読み取ります(下でリンクしている XPath の記事を参照してください)。
- ソースタイプ Constant、Local Variable、Global Variable、Number Range は、固定値や保存された値に使います。
header と exchange property、どちらを使うか
header はメッセージと一緒に移動します。レシーバーアダプターは header を呼び出し先のシステムに送ることができ、header は ProcessDirect 呼び出しで別の iFlow にも渡ります。exchange property は現在の iFlow の exchange の中にとどまり、それ自体がレシーバーに送られることはありません。
意外な挙動の多くは 2 つの点から生じます。header 名は大文字と小文字を区別しないため、${header.OrderID} と ${header.orderid} は同じ header を読みます。exchange property 名は大文字と小文字を区別するため、${property.OrderID} と ${property.orderId} は別のプロパティであり、後者はそもそも存在しないかもしれません。
- この iFlow の中だけで必要な値にはプロパティを使います。ID、カウンター、フラグ、保存しておくペイロードのコピーなどです。
- アダプターや次の iFlow が受け取るべき値には header を使い、tenant の外に出してはいけない header は削除します。
- 大きな値を header に入れないでください。呼び出しのたびに一緒に送られます。
Router と Filter での Simple 条件
Router のルートやタイプ Non-XML の Filter では、条件は Simple 式を値と比較したものです。よく使う演算子は =、!=、>、>=、<、<=、contains、in、regex で、and や or でつなぎます。テキストの値はシングルクォートで囲みます。
${header.orderType} = 'EXPRESS'
${property.amount} > 1000 and ${header.country} in 'DE,AT,CH'
${header.CamelHttpResponseCode} != '200'条件の中の header やプロパティが存在しない場合、条件は単に false になり、メッセージは別のルート、多くの場合はデフォルトのルートに進みます。未定義の header とプロパティに関する記事では、本番に届く前にこれを見つける方法を紹介しています。
Kitegra でできること
Kitegra は、SAP Integration Suite のデザイナー向けのブラウザー拡張機能です。デザイナーの入力欄に ${ または $ と入力すると、iFlow のその位置で使える名前が表示されます。Content Modifier、Groovy と JavaScript のスクリプト、その他 iFlow 内で設定される header とプロパティ、SAP と Camel の標準 header と式、{{…}} パラメーター、変数、Data Store 名です。一部の経路でしか設定されない名前には「一部のパスでのみ設定」と表示されます。
Lint パネルは、閉じていない ${、式の中の余分なスペース、iFlow のどこでも設定されていない header やプロパティを指摘します。XPath の行では、サンプルペイロードを渡すとパスの候補も表示されます。詳しくは XPath の記事を参照してください。拡張機能が iFlow の内容を保存、デプロイ、編集することはありません。tenant が変更されるのは、名前の付いた 4 つの操作のいずれかをクリックしたときだけで、これらの操作はオフにすることもできます。
式が実際にどんな値になるのかを確かめるには、メッセージをステップごとにトレースし、各ステップの前の header とプロパティを確認してください。
Kitegra アカウントがなくても、モジュールごとに 5 つの iFlow で使えます。Free プランは 50、Starter は 100、Pro は 300 まで対応します。チームプランではメンバー全員が Pro を使え、Startup Team はモジュールごとに 300 の iFlow、Growth Team と Scale Team は上限なしです。Kitegra のローンチ期間中は、Free プランを含め、サインインしているすべての人がすべてのツールを使えます。プランを比較する。
次の iFlow で試してみましょう
Kitegra が SAP Integration Suite のデザイナーで何をするのかを読むか、Kitegra のほかの Chrome 拡張機能と並べて確認できます。
よくある質問
SAP CPI で ${header.x} と ${property.x} の違いは何ですか?
${header.x} はメッセージ header を読みます。header はメッセージと一緒に移動し、レシーバーや別の iFlow に届くことがあります。${property.x} は exchange property を読み、これは現在の iFlow の中にとどまります。
header 名とプロパティ名は大文字と小文字を区別しますか?
header 名は区別しません。${header.OrderID} と ${header.orderid} は同じ header を読みます。exchange property 名は区別するため、${property.OrderID} と ${property.orderId} は別のプロパティです。
同じ Content Modifier でプロパティから設定した header が空になるのはなぜですか?
Content Modifier は header テーブル、プロパティテーブル、ボディの順に評価します。header は同じステップで設定されるプロパティを読めないため、プロパティは手前のステップで設定してください。
今日の日付をファイル名や入力欄に入れるにはどうすればよいですか?
${date:now:yyyy-MM-dd} を使います。Java の日付パターンなら何でも使え、たとえば ${date:now:yyyyMMddHHmmss} でタイムスタンプになります。
{{parameter}} は Simple 式ですか?
いいえ。{{…}} は外部化パラメーターを表し、iFlow のデプロイ時に一度だけ置き換えられます。${…} は Camel がメッセージごとに評価します。
式が存在しない header を指定するとどうなりますか?
エラーにならずに空の値を返すため、問題は後になって誤ったルートや空の欄として現れます。Lint チェックやガード用のステップを入れておけば、もっと早く見つかります。