第29章 CXF


CXF コンポーネント

cxf: コンポーネントは、CXF でホストされる JAX-WS サービスに接続するための Apache CXF との統合を提供します。
Maven ユーザーは、このコンポーネントの pom.xml に以下の依存関係を追加する必要があります。
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-cxf</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>
Copy to Clipboard Toggle word wrap
注記
CXF の依存関係については、 WHICH-JARS テキストファイルを参照してください。
注記
CXF をコンシューマーとして使用する場合、CAMEL:CXF Bean コンポーネント を使用すると、処理からメッセージペイロードを RESTful または SOAP Web サービスとして受信する方法を計算できます。これは、多量のトランスポートを使用して Web サービスを消費する可能性があります。Bean コンポーネントの設定も簡単で、Camel および CXF を使用して Web サービスを実装する最も高速な方法を提供します。
注記
ストリーミングモードで CXF を使用する場合(DataFormat オプションを参照)、Stream caching も読み取ります。

Camel on EAP デプロイメント

このコンポーネントは、Red Hat JBoss Enterprise Application Platform (JBoss EAP) コンテナー上で簡素化されたデプロイメントモデルを提供する Camel on EAP (Wildfly Camel) フレームワークによってサポートされます。このモデルの詳細は、Deploying into a Web Server の Apache Camel on JBoss EAP の章を参照してください
CXF コンポーネントは、Apache CXF も使用する JBoss EAP webservices サブシステムと統合します。詳細は、JAX-WS を参照してください。
注記
現在、Camel on EAP サブシステムは CXF または Restlet コンシューマーをサポートし ません。ただし、CamelProxy を使用して CXF コンシューマーの動作を模倣できます。

URI 形式

cxf:bean:cxfEndpoint[?options]
Copy to Clipboard Toggle word wrap
cxfEndpoint は、Spring Bean レジストリーの Bean を参照する Bean ID を表します。この URI 形式では、ほとんどのエンドポイントの詳細を Bean 定義で指定します。
cxf://someAddress[?options]
Copy to Clipboard Toggle word wrap
someAddress は CXF エンドポイントのアドレスを指定します。この URI 形式では、ほとんどのエンドポイントの詳細は オプションを使用して指定されます。
上記のいずれかのスタイルでは、以下のように URI にオプションを追加できます。
cxf:bean:cxfEndpoint?wsdlURL=wsdl/hello_world.wsdl&dataFormat=PAYLOAD
Copy to Clipboard Toggle word wrap

オプション

Expand
名前 必須 説明
wsdlURL いいえ
WSDL の場所。WSDL はデフォルトでエンドポイントアドレスから取得されます。以下に例を示します。
file://local/wsdl/hello.wsdl または wsdl/hello.wsdl
serviceClass はい
SEI (サービスエンドポイントインターフェイス)クラスの名前。このクラスは JSR181 アノテーションを持つことができますが、必須ではありません。  2.0 以降、このオプションは POJO モードでのみ必要です。wsdlURL オプションを指定すると、PAYLOAD モードおよび MESSAGE モードに serviceClass は必要ありません。serviceClass なしで wsdlURL オプションを使用する場合は、serviceName および portName (Spring 設定の endpointName)オプションを指定する 必要 があります。
2.0 以降、# 表記を使用してレジストリーから serviceClass オブジェクトインスタンスを参照できます。
Spring AOP プロキシー以外の場合は Object.getClass ().getName ()メソッドに依存するため、参照されるオブジェクトは Proxy (Spring AOP Proxy は OK)にすること はできません。
2.8 以降、 PAYLOAD モードと MESSAGE モードの wsdlURL オプションと serviceClass オプションの両方を省略できます。省略すると、CXF Dispatch モードを容易にするために、任意の XML 要素を PAYLOAD モードで CxfPayload のボディーに配置できます。
例: org.apache.camel.Hello
serviceName WSDL に複数の serviceName が存在する場合のみ
このサービスが実装しているサービス名。wsdl:service@name にマップされます。以下に例を示します。
{http://org.apache.camel}ServiceName
endpointName serviceName の下に複数の portName が存在し、Camel 2.2 以降の camel-cxf コンシューマーに必要です。
このサービスが実装しているポート名は、wsdl:port@name にマップされます。以下に例を示します。
{http://org.apache.camel}PortName
dataFormat いいえ CXF エンドポイントがサポートするメッセージデータ形式。使用できる値は POJO (デフォルト)PAYLOADMESSAGE です。
relayHeaders いいえ このオプションについては、relayHeadersオプション の説明を参照してください。ルートに CXF エンドポイントリレーヘッダーが必要です。現在、dataFormat=POJOデフォルト:true:truefalse
wrapped いいえ CXF エンドポイントプロデューサーが呼び出す操作の種類。使用できる値は truefalse (デフォルト) です。
wrappedStyle いいえ 2.5.0 以降、パラメーターが SOAP ボディーでどのように表現されるかを記述する WSDL スタイル。値が false の場合、CXF はドキュメントリテラルのアンラップスタイルを選択します。値が true の場合、CXF はドキュメントリテラルラップスタイルを選択します。
setDefaultBus いいえ 非推奨: このエンドポイントにデフォルトの CXF バスを使用するかどうかを指定します。使用できる値は truefalse (デフォルト) です。このオプションは非推奨となり、Camel 2.16 以降では defaultBus を使用する必要があります。
defaultBus いいえ 非推奨: このエンドポイントにデフォルトの CXF バスを使用するかどうかを指定します。使用できる値は truefalse (デフォルト) です。このオプションは非推奨となり、Camel 2.16 以降では defaultBus を使用する必要があります。
bus いいえ
# 表記を使用してレジストリーからバスオブジェクトを参照します(例: bus=#busName )。参照オブジェクトは org.apache.cxf.Bus のインスタンスである必要があります。
デフォルトでは、は CXF Bus Factory によって作成されたデフォルトのバスを使用します。
cxfBinding いいえ
# 表記を使用して、レジストリーから CXF バインディングオブジェクトを参照します(例: cxfBinding=#bindingName )。参照されるオブジェクトは org.apache.camel.component.cxf.CxfBinding のインスタンスである必要があります。
headerFilterStrategy いいえ # 表記を使用して、レジストリーからヘッダーフィルターストラテジーオブジェクトを参照します(例: headerFilterStrategy=#strategyName )。参照されるオブジェクトは org.apache.camel.spi.HeaderFilterStrategy のインスタンスである必要があります。
loggingFeatureEnabled いいえ 新しい 2.3 では、このオプションは、インバウンドおよびアウトバウンド SOAP メッセージをログに書き込む CXF Logging Feature を有効にします。使用できる値は truefalse (デフォルト) です。
defaultOperationName いいえ
2.4 の新機能として、このオプションはリモートサービスを呼び出す CxfProducer によって使用されるデフォルトの operationName を設定します。以下に例を示します。
defaultOperationName=greetMe
defaultOperationNamespace いいえ
2.4 の新機能として、このオプションはリモートサービスを呼び出す CxfProducer によって使用されるデフォルトの operationNamespace を設定します。以下に例を示します。
defaultOperationNamespace= http://apache.org/hello_world_soap_http
同期 いいえ 2.5 の新機能として、このオプションにより、CXF エンドポイントで sync または async API を使用して基礎となる作業を実行できます。デフォルト値は false です。つまり、camel-cxf エンドポイントはデフォルトで非同期 API の使用を試行します。
publishedEndpointUrl いいえ
2.5 の新機能で、このオプションは、サービスアドレス URL と ?wsdl を使用してアクセスされる公開された WSDL に表示されるエンドポイント URL を上書きします。以下に例を示します。
publshedEndpointUrl=http://example.com/service
properties.propName いいえ Camel 2.8: エンドポイント URI でカスタム CXF プロパティーを設定できます。たとえば、properties.mtom-enabled=true を設定して MTOM を有効にします。呼び出しの開始時に CXF がスレッドを切り替えないようにするには、properties.org.apache.cxf.interceptor.OneWayProcessorInterceptor.USE_ORIGINAL_THREAD=true を設定します。
allowStreaming いいえ 2.8.2 の新機能このオプションは、PAYLOAD モード(以下を参照)で実行しているときに CXF コンポーネントを制御するか、またはペイロードを DOM 要素に解析するか、場合によってはストリーミングを可能にする javax.xml.transform.Source オブジェクトとしてペイロードを保持するかどうかを制御します。
skipFaultLogging いいえ 2.11 の新機能このオプションは、PhaseInterceptorChain がキャッチする Fault のロギングをスキップするかどうかを制御します。
cxfEndpointConfigurer
いいえ
Camel 2.11 の新機能このオプションは、org.apache.camel.component.cxf.CxfEndpointConfigurer which supports の実装を適用して、プログラム的に CXF エンドポイントを設定できます。Camel 2.15.0 以降、ユーザーは CxfEndpointConfigurer の configure{Server|Client} メソッドを実装して CXF サーバーおよびクライアントを設定できます。
username
いいえ
Camel 2.12.3 の新機能。このオプションは、CXF クライアントのユーザー名の基本認証情報を設定するために使用されます。
password
いいえ
Camel 2.12.3 の新機能。このオプションは、CXF クライアントのパスワードの基本認証情報を設定するために使用されます。
continuationTimeout
いいえ
Camel 2.14.0 の新機能は、CXF サーバーが Jetty または Servlet トランスポートを使用している場合にデフォルトで CxfConsumer で使用できる CXF 継続タイムアウトを設定するために使用されます。( Camel 2.14. 0 よりも前のバージョンでは、CxfConsumer は継続タイムアウトを 0 に設定するだけで、継続一時停止操作がタイムアウトしないことを意味します)。
デフォルト: 30000 : continuation=80000
serviceName および portNameQNames であるため、上記の例のようにそれらを {namespace} の接頭辞を指定するようにしてください。

データ形式の説明

Expand
DataFormat 説明
POJO POJO (旧称の Java オブジェクト)は、ターゲットサーバーで呼び出されるメソッドの Java パラメーターです。Protocol および Logical JAX-WS ハンドラーの両方がサポートされます。
PAYLOAD PAYLOAD は、CXF エンドポイントのメッセージ設定の適用後のメッセージペイロード( soap:bodyの内容)です。プロトコル JAX-WS ハンドラーのみがサポートされます。論理 JAX-WS ハンドラーはサポートされていません。
MESSAGE MESSAGE は、トランスポート層から受信される生のメッセージです。Stream をタッチまたは変更することは意図されていません。このような DataFormat を使用している場合は、CXF インターセプターの一部が削除されるため、camel-cxf コンシューマーと JAX-WS ハンドラーがサポートされていない後に soap ヘッダーは表示されません。
CXF_MESSAGE Camel 2.8.2 の新機能のCXF_MESSAGE では、メッセージをトランスポート層から raw SOAP メッセージに変換して CXF インターセプターの完全な機能を呼び出すことができます。
エクスチェンジのプロパティー CamelCXFDataFormat を取得することで、エクスチェンジのデータフォーマットモードを決定できます。Exchange キー定数は org.apache.camel.component.cxf.CxfConstants.DATA_FORMAT_PROPERTY で定義されます。

Apache Aries Blueprint での CXF エンドポイントの設定

Camel 2.8 以降、CXF エンドポイントに Aries Blueprint dependency injection を使用するためのサポートがあります。スキーマは Spring スキーマと非常に似ているため、移行は非常に透過的です。
以下に例を示します。
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
            xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
 	   xmlns:cxfcore="http://cxf.apache.org/blueprint/core"
            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
 
       <camel-cxf:cxfEndpoint id="routerEndpoint"
                      address="http://localhost:9001/router"
                      serviceClass="org.apache.servicemix.examples.cxf.HelloWorld">
         <camel-cxf:properties>
             <entry key="dataFormat" value="MESSAGE"/>
         </camel-cxf:properties>
      </camel-cxf:cxfEndpoint>
 
      <camel-cxf:cxfEndpoint id="serviceEndpoint"
			address="http://localhost:9000/SoapContext/SoapPort"
                     serviceClass="org.apache.servicemix.examples.cxf.HelloWorld">
    </camel-cxf:cxfEndpoint>

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
        <route>
            <from uri="routerEndpoint"/>
            <to uri="log:request"/>
        </route>
    </camelContext>

</blueprint>


Copy to Clipboard Toggle word wrap
現在、endpoint 要素は最初にサポートされている CXF namespacehandler です。
Spring の場合と同様に Bean 参照を使用することもできます。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
           xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
           xmlns:cxf="http://cxf.apache.org/blueprint/core"
           xmlns:camel="http://camel.apache.org/schema/blueprint"
           xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"
           xsi:schemaLocation="
             http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
             http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd
             http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
             ">

    <camelcxf:cxfEndpoint id="reportIncident"
                     address="/camel-example-cxf-blueprint/webservices/incident"
                     wsdlURL="META-INF/wsdl/report_incident.wsdl"
                     serviceClass="org.apache.camel.example.reportincident.ReportIncidentEndpoint">
    </camelcxf:cxfEndpoint>

    <bean id="reportIncidentRoutes" class="org.apache.camel.example.reportincident.ReportIncidentRoutes" />

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
        <routeBuilder ref="reportIncidentRoutes"/>
    </camelContext>

</blueprint>


Copy to Clipboard Toggle word wrap

MESSAGE モードで CXF の LoggingOutInterceptor を有効にする方法

CXF の LoggingOutInterceptor は、ロギングシステム()に対応するアウトバウンドメッセージを出力します。java.util.loggingLoggingOutInterceptorPRE_STREAM フェーズであるため(ただし、PRE_STREAM フェーズは MESSAGE モードで削除)、WRITE フェーズ中に実行する LoggingOutInterceptor を設定する必要があります。以下は例です。
   <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor">
        <!--  it really should have been user-prestream but CXF does have such phase! -->
        <constructor-arg value="target/write"/> 
   </bean>
   		
<cxf:cxfEndpoint id="serviceEndpoint" address="http://localhost:9002/helloworld"
	serviceClass="org.apache.camel.component.cxf.HelloService">
	<cxf:outInterceptors>
	    <ref bean="loggingOutInterceptor"/>
	</cxf:outInterceptors>
	<cxf:properties>
		<entry key="dataFormat" value="MESSAGE"/>
	</cxf:properties>
</cxf:cxfEndpoint>
Copy to Clipboard Toggle word wrap

relayHeaders オプションの説明

JAXWS WSDL ファースト開発者 の視点から、帯域 および帯域外 ヘッダーがあります。
インバウンド ヘッダーは、SOAP ヘッダーなどのエンドポイントの WSDL バインディングコントラクトの一部として明示的に定義されるヘッダーです。
帯域外 ヘッダーはネットワーク経由でシリアライズされるヘッダーですが、WSDL バインディングコントラクトの一部ではありません。
ヘッダーのリレー/フィルターリングは双方向です。
ルートに CXF エンドポイントがあり、開発者が SOAP ヘッダーなどのオンワイヤヘッダーを別の JAXWS エンドポイントによって消費されるルートにリレーする必要がある場合、relayHeaders はデフォルト値の true に設定する必要があります。

POJO モードでのみ利用可能

relayHeaders=true 設定は、ヘッダーをリレーする意図を表します。指定されたヘッダーがリレーされるかどうかに関する実際の決定は、MessageHeadersRelay インターフェイスを実装するプラグ可能なインスタンスに委譲されます。MessageHeadersRelay の具体的な実装は、ヘッダーをリレーする必要があるかどうかを判断するために参照されます。よく知られている SOAP 名前空間にバインドする SoapMessageHeadersRelay の実装があります。現在、帯域外ヘッダーのみがフィルターされ、relayHeaders=true の場合に帯域内ヘッダーが常にリレーされます。ネットワーク上でヘッダーがあり、その名前空間がランタイムに認識されていない場合は、フォールバック DefaultMessageHeadersRelay が使用され、単純にすべてのヘッダーをリレーできます。
relayHeaders=false 設定は、すべてのヘッダー(in-band および out-of-band)が破棄されることをアサートします。
独自の MessageHeadersRelay 実装を上書きするか、リレーのリストに追加の実装を追加できます。事前に読み込んだリレーインスタンスをオーバーライドするには、MessageHeadersRelay 実装サービスが、上書きするものと同じ名前空間であることを確認します。また、オーバーライドするリレーは、上書きする名前空間としてすべての名前空間に対応する必要があります。そうしないと、インスタンスマッピングをリレーする名前空間に曖昧さが発生するため、ルート起動時にランタイム例外が出力されます。
<cxf:cxfEndpoint ...>
   <cxf:properties>
     <entry key="org.apache.camel.cxf.message.headers.relays">
       <list>
         <ref bean="customHeadersRelay"/>
       </list>
     </entry>
   </cxf:properties>
 </cxf:cxfEndpoint>
 <bean id="customHeadersRelay" class="org.apache.camel.component.cxf.soap.headers.CustomHeadersRelay"/>
Copy to Clipboard Toggle word wrap
ここで、ヘッダーをリレー/ドロップする方法を示すテストを確認してください。

リリース 2.0 以降の変更点

  • POJO モードおよび PAYLOAD モードがサポートされます。POJO モードでは、帯域内ヘッダーが処理され、CXF によってヘッダーリストから削除されたため、帯域外メッセージヘッダーのみがフィルターリングできます。帯域内ヘッダーは、POJO モードで MessageContentList に組み込まれます。camel-cxf コンポーネントは、MessageContentList から帯域内ヘッダーの削除を試行しようとします。帯域内ヘッダーのフィルターリングが必要な場合、PAYLOAD モードを使用するか、CXF インターセプター/JAXWS ハンドラーのプラグインを CXF エンドポイントに使用してください。
  • Message Header Relay メカニズムは CxfHeaderFilterStrategy に統合されました。relayHeaders オプション、そのセマンティクス、およびデフォルト値は同じですが、CxfHeaderFilterStrategy のプロパティーです。以下は、設定例です。
    <bean id="dropAllMessageHeadersStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy">
    
        <!--  Set relayHeaders to false to drop all SOAP headers -->
        <property name="relayHeaders" value="false"/>
        
    </bean>
    
    Copy to Clipboard Toggle word wrap
    次に、エンドポイントは CxfHeaderFilterStrategy を参照できます。
    <route>
        <from uri="cxf:bean:routerNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/>          
        <to uri="cxf:bean:serviceNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/>
    </route>
    
    Copy to Clipboard Toggle word wrap
  • MessageHeadersRelay インターフェイスは若干変更され、MessageHeaderFilter に変更されました。これは CxfHeaderFilterStrategy のプロパティーです。以下は、ユーザー定義のメッセージヘッダーフィルターを設定する例です。
    <bean id="customMessageFilterStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy">
        <property name="messageHeaderFilters">
            <list>
                <!--  SoapMessageHeaderFilter is the built in filter.  It can be removed by omitting it. -->
                <bean class="org.apache.camel.component.cxf.common.header.SoapMessageHeaderFilter"/>
                
                <!--  Add custom filter here -->    
                <bean class="org.apache.camel.component.cxf.soap.headers.CustomHeaderFilter"/>
            </list>
        </property>
    </bean>
    
    Copy to Clipboard Toggle word wrap
  • relayHeaders 以外に、CxfHeaderFilterStrategy で設定できる新しいプロパティーがあります。
Expand
名前 説明 type 必須 ? デフォルト値
relayHeaders すべてのメッセージヘッダーがメッセージヘッダーフィルターによって処理されます。 boolean いいえ true (1.6.1 動作)
relayAllMessageHeaders すべてのメッセージヘッダーが伝播されます(メッセージヘッダーフィルターによる処理なし)。 boolean いいえ false (1.6.1 の動作)
allowFilterNamespaceClash 2 つのフィルターがアクティベーション namespace で重複する場合、プロパティーはその処理方法を制御します。値が true の場合、最後の値が優先されます。値が false の場合、例外が発生します。 boolean いいえ false (1.6.1 の動作)

Spring での CXF エンドポイントの設定

以下の Spring 設定ファイルで CXF エンドポイントを設定できます。また、エンドポイントを camelContext タグに埋め込むこともできます。サービスエンドポイントを呼び出す場合、operationName および operationNamespace ヘッダーを、呼び出す操作を明示的に設定できます。
注記 Camel 2.x では、http://camel.apache.org/schema/cxf を CXF エンドポイントのターゲット namespace として使用するよう変更します。
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cxf="http://camel.apache.org/schema/cxf"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd     ">
 ...

Copy to Clipboard Toggle word wrap
注記
Apache Camel 2.x では、http://activemq.apache.org/camel/schema/cxfEndpoint 名前空間が http://camel.apache.org/schema/cxf に変更されました。
ルート beans 要素に指定された JAX-WS schemaLocation 属性を含めるようにしてください。これにより、CXF はファイルを検証でき、必須です。また、< cxf:cxfEndpoint/ > タグの末尾にある namespace 宣言にも注意してください。これらの宣言は、組み合わせた {namespace}localName 構文がこのタグの属性値ではサポートされていないためです。
cxf:cxfEndpoint 要素は、多くの追加属性をサポートします。
Expand
名前
PortName このサービスが実装しているエンドポイント名は、wsdl:port@name にマップされます。ns:PORT_NAME の形式で、ns はこのスコープで有効な namespace 接頭辞になります。
serviceName このサービスが実装しているサービス名。wsdl:service@name にマップされます。ns:SERVICE_NAME の形式で、ns はこのスコープで有効な namespace 接頭辞になります。
wsdlURL WSDL の場所。クラスパス、ファイルシステム上、またはリモートでホストできます。
bindingId 使用するサービスモデルの bindingId
address サービスの公開アドレス。
bus JAX-WS エンドポイントで使用されるバス名。
serviceClass JSR181 アノテーションを持つことができる SEI (Service Endpoint Interface)クラスのクラス名。
また、多くの子要素もサポートします。
Expand
名前
cxf:inInterceptors このエンドポイントの受信インターセプター。<bean&gt ; または &lt; ref> の リスト。
cxf:inFaultInterceptors このエンドポイントの受信障害インターセプター。<bean&gt ; または &lt; ref> の リスト。
cxf:outInterceptors このエンドポイントの送信インターセプター。<bean&gt ; または &lt; ref> の リスト。
cxf:outFaultInterceptors このエンドポイントの送信障害インターセプター。<bean&gt ; または &lt; ref> の リスト。
cxf:properties JAX-WS エンドポイントに提供する必要があるプロパティーマップ。以下を参照してください。
cxf:handlers JAX-WS エンドポイントに提供する必要がある JAX-WS ハンドラーリスト。以下を参照してください。
cxf:dataBinding エンドポイントで使用する DataBinding を指定できます。これは、Spring < bean class="MyDataBinding"/ > 構文を使用して指定できます。
cxf:binding このエンドポイントで使用する BindingFactory を指定できます。これは、Spring < bean class="MyBindingFactory"/ > 構文を使用して指定できます。
cxf:features このエンドポイントのインターセプターを保持する機能。< bean> s または< ref> sの一覧
cxf:schemaLocations 使用するエンドポイントのスキーマの場所。< schemaLocation> の一覧
cxf:serviceFactory このエンドポイントで使用するサービスファクトリー。これは、Spring < bean class="MyServiceFactory"/> 構文を使用して指定でき ます。
インターセプター、プロパティー、およびハンドラーの提供方法を示す高度な例は、以下を参照してください。 http://cwiki.apache.org/CXF20DOC/jax-ws-configuration.html
注記
CXF:properties を使用して、以下のように Spring 設定ファイルの CXF エンドポイントの dataFormat および setDefaultBus プロパティーを設定できます。
<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/router"
     serviceClass="org.apache.camel.component.cxf.HelloService"
     endpointName="s:PortName"
     serviceName="s:ServiceName"
     xmlns:s="http://www.example.com/test">
     <cxf:properties>
       <entry key="dataFormat" value="MESSAGE"/>
       <entry key="setDefaultBus" value="true"/>
     </cxf:properties>
   </cxf:cxfEndpoint>
Copy to Clipboard Toggle word wrap

How to make the camel-cxf component use log4j instead of java.util.logging

CXF のデフォルトロガーは java.util.logging です。log4j に変更するには、以下の手順を実行します。META-INF/cxf/org.apache.cxf.logger という名前のクラスパスにファイルを作成します。このファイルには、1 行にコメントのない org.apache.cxf.common.logging.Log4jLogger クラスの完全修飾名が含まれている必要があります。

How to let camel-cxf response message with xml start document

PHP などの SOAP クライアントを使用している場合は、CXF は XML 開始ドキュメント <?xml version="1.0" encoding="utf-8"?> を追加しないため、この種類のエラーが発生します。
Error:sendSms: SoapFault exception: [Client] looks like we got no XML document in [...]
Copy to Clipboard Toggle word wrap
この問題を解決するには、XML 開始ドキュメントを作成するように StaxOutInterceptor に指示するだけです。
public class WriteXmlDeclarationInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    public WriteXmlDeclarationInterceptor() {
        super(Phase.PRE_STREAM);
        addBefore(StaxOutInterceptor.class.getName());
    }

    public void handleMessage(SoapMessage message) throws Fault {
        message.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE);        
    }

}
Copy to Clipboard Toggle word wrap
このようなカスタマーインターセプターを追加し、camel-cxf エンドユーザーに設定できます。
<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port2}/CXFGreeterRouterTest/CamelContext/RouterPort"
 		serviceClass="org.apache.hello_world_soap_http.GreeterImpl"
 		skipFaultLogging="true">
     <cxf:outInterceptors>
         <!-- This interceptor will force the CXF server send the XML start document to client -->
         <bean class="org.apache.camel.component.cxf.WriteXmlDeclarationInterceptor"/>
     </cxf:outInterceptors>
     <cxf:properties>
         <!-- Set the publishedEndpointUrl which could override the service address from generated WSDL as you want -->
         <entry key="publishedEndpointUrl" value="http://www.simple.com/services/test" />
     </cxf:properties>
 </cxf:cxfEndpoint>
Copy to Clipboard Toggle word wrap
または、Camel 2.4 を使用している場合は、このようなメッセージヘッダーを追加し ます。
 // set up the response context which force start document
 Map<String, Object> map = new HashMap<String, Object>();
 map.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE);
 exchange.getOut().setHeader(Client.RESPONSE_CONTEXT, map);
Copy to Clipboard Toggle word wrap

POJO データ形式で camel-cxf エンドポイントからメッセージを消費する方法

camel-cxf エンドポイントコンシューマー POJO データ形式は cxf invoker をベースとしているため、メッセージヘッダーには CxfConstants.OPERATION_NAME という名前の プロパティーがあり、メッセージボディーは SEI メソッドパラメーターのリストです。
public class PersonProcessor implements Processor {

    private static final transient Logger LOG = LoggerFactory.getLogger(PersonProcessor.class);

    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        LOG.info("processing exchange in camel");

        BindingOperationInfo boi = (BindingOperationInfo)exchange.getProperty(BindingOperationInfo.class.toString());
        if (boi != null) {
            LOG.info("boi.isUnwrapped" + boi.isUnwrapped());
        }
        // Get the parameters list which element is the holder.
        MessageContentsList msgList = (MessageContentsList)exchange.getIn().getBody();
        Holder<String> personId = (Holder<String>)msgList.get(0);
        Holder<String> ssn = (Holder<String>)msgList.get(1);
        Holder<String> name = (Holder<String>)msgList.get(2);

        if (personId.value == null || personId.value.length() == 0) {
            LOG.info("person id 123, so throwing exception");
            // Try to throw out the soap fault message
            org.apache.camel.wsdl_first.types.UnknownPersonFault personFault =
                new org.apache.camel.wsdl_first.types.UnknownPersonFault();
            personFault.setPersonId("");
            org.apache.camel.wsdl_first.UnknownPersonFault fault =
                new org.apache.camel.wsdl_first.UnknownPersonFault("Get the null value of person name", personFault);
            // Since camel has its own exception handler framework, we can't throw the exception to trigger it
            // We just set the fault message in the exchange for camel-cxf component handling and return
            exchange.getOut().setFault(true);
            exchange.getOut().setBody(fault);
            return;
        }

        name.value = "Bonjour";
        ssn.value = "123";
        LOG.info("setting Bonjour as the response");
        // Set the response message, first element is the return value of the operation,
        // the others are the holders of method parameters
        exchange.getOut().setBody(new Object[] {null, personId, ssn, name});
    }

}
Copy to Clipboard Toggle word wrap

POJO データ形式で camel-cxf エンドポイントのメッセージを準備する方法

camel-cxf エンドポイントプロデューサーは cxf クライアント API に基づいています。最初にメッセージヘッダーで操作名を指定し、メソッドパラメーターをリストに追加し、このパラメーターリストでメッセージを初期化する必要があります。応答メッセージのボディーは messageContentsList で、その結果をリストから取得できます。
メッセージヘッダーで操作名を指定しない場合、CxfProducerdefaultOperationName from CxfEndpoint の使用を試行します。CxfEndpointdefaultOperationName が設定されていない場合、操作リストから最初の操作名が選択されます。
メッセージボディーからオブジェクトアレイを取得する場合は、以下のように message.getbody (Object[].class) を使用してボディーを取得できます。
Exchange senderExchange = new DefaultExchange(context, ExchangePattern.InOut);
final List<String> params = new ArrayList<String>();
// Prepare the request message for the camel-cxf procedure
params.add(TEST_MESSAGE);
senderExchange.getIn().setBody(params);
senderExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ECHO_OPERATION);

Exchange exchange = template.send("direct:EndpointA", senderExchange);

org.apache.camel.Message out = exchange.getOut();
// The response message's body is an MessageContentsList which first element is the return value of the operation,
// If there are some holder parameters, the holder parameter will be filled in the reset of List.
// The result will be extract from the MessageContentsList with the String class type
MessageContentsList result = (MessageContentsList)out.getBody();
LOG.info("Received output text: " + result.get(0));
Map<String, Object> responseContext = CastUtils.cast((Map<?, ?>)out.getHeader(Client.RESPONSE_CONTEXT));
assertNotNull(responseContext);
assertEquals("We should get the response context here", "UTF-8", responseContext.get(org.apache.cxf.message.Message.ENCODING));
assertEquals("Reply body on Camel is wrong", "echo " + TEST_MESSAGE, result.get(0));
Copy to Clipboard Toggle word wrap

PAYLOAD データ形式で camel-cxf エンドポイントのメッセージを処理する方法

Apache Camel 2.0: CxfMessage.getBody () は、SOAP メッセージヘッダーおよび Body 要素のゲッターを持つ org.apache.camel.component.cxf.CxfPayload オブジェクトを返します。この変更により、Apache Camel メッセージからネイティブ CXF メッセージを切り離すことができます。
protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from(SIMPLE_ENDPOINT_URI + "&dataFormat=PAYLOAD").to("log:info").process(new Processor() {
                @SuppressWarnings("unchecked")
                public void process(final Exchange exchange) throws Exception {                        
                    CxfPayload<SoapHeader> requestPayload = exchange.getIn().getBody(CxfPayload.class);
                    List<Source> inElements = requestPayload.getBodySources();
                    List<Source> outElements = new ArrayList<Source>();
                    // You can use a customer toStringConverter to turn a CxfPayLoad message into String as you want                        
                    String request = exchange.getIn().getBody(String.class);
                    XmlConverter converter = new XmlConverter();
                    String documentString = ECHO_RESPONSE;
                    
                    Element in = new XmlConverter().toDOMElement(inElements.get(0));
                    // Just check the element namespace
                    if (!in.getNamespaceURI().equals(ELEMENT_NAMESPACE)) {
                        throw new IllegalArgumentException("Wrong element namespace");
                    }
                    if (in.getLocalName().equals("echoBoolean")) {
                        documentString = ECHO_BOOLEAN_RESPONSE;
                        checkRequest("ECHO_BOOLEAN_REQUEST", request);
                    } else {
                        documentString = ECHO_RESPONSE;
                        checkRequest("ECHO_REQUEST", request);
                    }
                    Document outDocument = converter.toDOMDocument(documentString);
                    outElements.add(new DOMSource(outDocument.getDocumentElement()));
                    // set the payload header with null
                    CxfPayload<SoapHeader> responsePayload = new CxfPayload<SoapHeader>(null, outElements, null);
                    exchange.getOut().setBody(responsePayload); 
                }
            });
        }
    };
}
Copy to Clipboard Toggle word wrap

POJO モードで SOAP ヘッダーを取得および設定する方法

POJO は、CXF エンドポイントが Camel エクスチェンジを生成または消費した場合に、データフォーマットが Java オブジェクトのリスト であることを意味します。Apache Camel はメッセージボディーをこのモードで POJO として公開しますが、CXF コンポーネントは引き続き SOAP ヘッダーの読み取りおよび書き込みへのアクセスを提供します。ただし、CXF インターセプターは処理後にヘッダーリストから帯域外 SOAP ヘッダーを削除するため、POJO モードで使用できるのは帯域外 SOAP ヘッダーのみです。
以下の例は、SOAP ヘッダーの取得/設定方法を示しています。ある CXF エンドポイントから別の CXF エンドポイントに転送するルートがあるとします。つまり、SOAP Client -> Apache Camel -> CXF service です。要求が CXF サービスに送信される前に(1)で SOAP ヘッダーの取得/挿入に 2 つのプロセッサーを添付し、応答が SOAP クライアントに戻る前に(2)。この例では プロセッサー(1)および(2)は InsertRequestOutHeaderProcessor および InsertResponseOutHeaderProcessor です。ルートは以下のようになります。
<route>
    <from uri="cxf:bean:routerRelayEndpointWithInsertion"/>
    <process ref="InsertRequestOutHeaderProcessor" />
    <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/>
    <process ref="InsertResponseOutHeaderProcessor" />
</route>
Copy to Clipboard Toggle word wrap
2.x で は、SOAP ヘッダーは Apache Camel Message ヘッダーとの間で伝播されます。Apache Camel メッセージヘッダー名は org.apache.cxf.headers.Header.list で、CXF (org.apache.cxf.headers.Header.HEADER_LIST)で定義された定数です。ヘッダーの値は、CXF SoapHeader オブジェクト(org.apache.cxf.binding.soap.SoapHeader)の List<> です。以下のスニペットは InsertResponseOutHeaderProcessor です(応答メッセージに新しい SOAP ヘッダーを挿入します)。InsertResponseOutHeaderProcessorInsertRequestOutHeaderProcessor の両方で SOAP ヘッダーにアクセスする方法は、実際には同じです。2 つのプロセッサーの唯一の違いは、挿入された SOAP ヘッダーの方向を設定することです。
public static class InsertResponseOutHeaderProcessor implements Processor {

    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        // You should be able to get the header if exchange is routed from camel-cxf endpoint
        List<SoapHeader> soapHeaders = CastUtils.cast((List<?>)exchange.getIn().getHeader(Header.HEADER_LIST));
        if (soapHeaders == null) {
            // we just create a new soap headers in case the header is null
            soapHeaders = new ArrayList<SoapHeader>();
        }

        // Insert a new header
        String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><outofbandHeader "
            + "xmlns=\"http://cxf.apache.org/outofband/Header\" hdrAttribute=\"testHdrAttribute\" "
            + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" soap:mustUnderstand=\"1\">"
            + "<name>New_testOobHeader</name><value>New_testOobHeaderValue</value></outofbandHeader>";
        SoapHeader newHeader = new SoapHeader(soapHeaders.get(0).getName(),
                       DOMUtils.readXml(new StringReader(xml)).getDocumentElement());
        // make sure direction is OUT since it is a response message.
        newHeader.setDirection(Direction.DIRECTION_OUT);
        //newHeader.setMustUnderstand(false);
        soapHeaders.add(newHeader);
        
    }
    
}
Copy to Clipboard Toggle word wrap

PAYLOAD モードで SOAP ヘッダーを取得および設定する方法

PAYLOAD モードで SOAP メッセージ(CxfPayload オブジェクト)にアクセスする方法はすでに説明されています( 「PAYLOAD データ形式で camel-cxf エンドポイントのメッセージを処理する方法」を参照してください)。
CxfPayload オブジェクトを取得したら、DOM Elements (SOAP ヘッダー)の List を返す CxfPayload.getHeaders() メソッドを呼び出すことができます。
from(getRouterEndpointURI()).process(new Processor() {
    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        CxfPayload<SoapHeader> payload = exchange.getIn().getBody(CxfPayload.class);
        List<Source> elements = payload.getBodySources();
        assertNotNull("We should get the elements here", elements);
        assertEquals("Get the wrong elements size", 1, elements.size());
                
        Element el = new XmlConverter().toDOMElement(elements.get(0));
        elements.set(0, new DOMSource(el));
        assertEquals("Get the wrong namespace URI", "http://camel.apache.org/pizza/types", 
                el.getNamespaceURI());
            
        List<SoapHeader> headers = payload.getHeaders();
        assertNotNull("We should get the headers here", headers);
        assertEquals("Get the wrong headers size", headers.size(), 1);
        assertEquals("Get the wrong namespace URI", 
                ((Element)(headers.get(0).getObject())).getNamespaceURI(), 
                "http://camel.apache.org/pizza/types");         
    }
    
})
.to(getServiceEndpointURI());
Copy to Clipboard Toggle word wrap
Camel 2.16.0 以降、「POJO モードで SOAP ヘッダーを取得および設定する方法」 で説明されているのと同じアプローチを使用して SOAP ヘッダーを設定または取得できます。org.apache.cxf.headers.Header.list ヘッダーを使用して、SOAP ヘッダーの一覧を取得および設定できるようになりました。つまり、ある Camel CXF エンドポイントから別の(SOAP Client -> Camel -> CXF サービス)に転送するルートがある場合、SOAP クライアントによって送信された SOAP ヘッダーも CXF サービスに転送されるようになりました。ヘッダーの転送を希望しない場合は、org.apache.cxf.headers.Header.list Camel ヘッダーから削除します。

SOAP ヘッダーが MESSAGE モードで利用できない

SOAP 処理はスキップされるため、SOAP ヘッダーは MESSAGE モードでは利用できません。

Apache Camel から SOAP Fault を出力する方法

CXF エンドポイントを使用して SOAP リクエストを消費する場合、Camel コンテキストから SOAP Fault を出力する必要がある場合があります。基本的に、throwFault DSL を使用してこれを実行できます。POJOPAYLOAD、および MESSAGE データフォーマットで機能します。以下のように soap 障害を定義できます。
SOAP_FAULT = new SoapFault(EXCEPTION_MESSAGE, SoapFault.FAULT_CODE_CLIENT);
Element detail = SOAP_FAULT.getOrCreateDetail();
Document doc = detail.getOwnerDocument();
Text tn = doc.createTextNode(DETAIL_TEXT);
detail.appendChild(tn);
Copy to Clipboard Toggle word wrap
次に、以下のようにこれを出力します。
from(routerEndpointURI).setFaultBody(constant(SOAP_FAULT));
Copy to Clipboard Toggle word wrap
CXF エンドポイントが MESSAGE データ形式で機能している場合は、メッセージボディーに SOAP Fault メッセージを設定し、メッセージヘッダーに応答コードを設定できます。
from(routerEndpointURI).process(new Processor() {

    public void process(Exchange exchange) throws Exception {
        Message out = exchange.getOut();
        // Set the message body with the 
        out.setBody(this.getClass().getResourceAsStream("SoapFaultMessage.xml"));
        // Set the response code here
        out.setHeader(org.apache.cxf.message.Message.RESPONSE_CODE, new Integer(500));
    }

});
Copy to Clipboard Toggle word wrap
POJO データフォーマットでも同様です。Out ボディーに SOAP Fault を設定し、以下のように Message.setFault(true) を呼び出すことで障害を示すこともできます。
from("direct:start").onException(SoapFault.class).maximumRedeliveries(0).handled(true)
    .process(new Processor() {
        public void process(Exchange exchange) throws Exception {
            SoapFault fault = exchange
                .getProperty(Exchange.EXCEPTION_CAUGHT, SoapFault.class);
            exchange.getOut().setFault(true);
            exchange.getOut().setBody(fault);
        }

    }).end().to(serviceURI);
Copy to Clipboard Toggle word wrap

CXF エンドポイントの要求および応答コンテキストを伝播する方法

CXF クライアント API は、リクエストおよび応答コンテキストで操作を呼び出す方法を提供します。CXF エンドポイントプロデューサーを使用して外部 Web サービスを呼び出す場合は、リクエストコンテキストを設定し、以下のコードで応答コンテキストを取得できます。
        CxfExchange exchange = (CxfExchange)template.send(getJaxwsEndpointUri(), new Processor() {
             public void process(final Exchange exchange) {
                 final List<String> params = new ArrayList<String>();
                 params.add(TEST_MESSAGE);
                 // Set the request context to the inMessage
                 Map<String, Object> requestContext = new HashMap<String, Object>();
                 requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, JAXWS_SERVER_ADDRESS);
                 exchange.getIn().setBody(params);
                 exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext);
                 exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, GREET_ME_OPERATION);
             }
         });
         org.apache.camel.Message out = exchange.getOut();
         // The output is an object array, the first element of the array is the return value
         Object\[\] output = out.getBody(Object\[\].class);
         LOG.info("Received output text: " + output\[0\]);
         // Get the response context form outMessage
         Map<String, Object> responseContext = CastUtils.cast((Map)out.getHeader(Client.RESPONSE_CONTEXT));
         assertNotNull(responseContext);
         assertEquals("Get the wrong wsdl opertion name", "{http://apache.org/hello_world_soap_http}greetMe",
                      responseContext.get("javax.xml.ws.wsdl.operation").toString());

Copy to Clipboard Toggle word wrap

添付ファイルのサポート

POJO モード: Attachment および MTOM を備えた SOAP の両方がサポートされます(MTOM を有効にする場合は Payload モードの例を参照)。 ただし、添付付きの SOAP はテストされていません。 アタッチメントは POJO にマーシャリングおよびアンマーシャリングされるため、通常は添付ファイルを処理する必要はありません。 添付ファイルは、2.1 以降 Camel メッセージの添付に伝播されます。 そのため、Camel Message API による再添付が可能です。
DataHandler Message.getAttachment(String id)
Copy to Clipboard Toggle word wrap
をクリックします。
ペイロードモード: MTOM は 2.1 以降でサポートされています。添付ファイルは、上記の Camel Message API で取得できます。このモードでは SOAP 処理がないため、Attachment を使用した SOAP はサポートされません。
MTOM を有効にするには、CXF エンドポイントプロパティー mtom_enabled を true に設定します。(Spring でのみ実行できます)
<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port1}/CxfMtomRouterPayloadModeTest/jaxws-mtom/hello"
         wsdlURL="mtom.wsdl"
         serviceName="ns:HelloService"
         endpointName="ns:HelloPort"
         xmlns:ns="http://apache.org/camel/cxf/mtom_feature">

     <cxf:properties>
         <!--  enable mtom by setting this property to true -->
         <entry key="mtom-enabled" value="true"/>
         
         <!--  set the camel-cxf endpoint data fromat to PAYLOAD mode -->
         <entry key="dataFormat" value="PAYLOAD"/>
     </cxf:properties>
Copy to Clipboard Toggle word wrap
attachment で Camel メッセージを生成し、Payload モードで CXF エンドポイントに送信できます。
Exchange exchange = context.createProducerTemplate().send("direct:testEndpoint", new Processor() {

    public void process(Exchange exchange) throws Exception {
        exchange.setPattern(ExchangePattern.InOut);
        List&lt;Source> elements = new ArrayList&lt;Source>();
        elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement()));
        CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(),
            elements, null);
        exchange.getIn().setBody(body);
        exchange.getIn().addAttachment(MtomTestHelper.REQ_PHOTO_CID, 
            new DataHandler(new ByteArrayDataSource(MtomTestHelper.REQ_PHOTO_DATA, "application/octet-stream")));

        exchange.getIn().addAttachment(MtomTestHelper.REQ_IMAGE_CID, 
            new DataHandler(new ByteArrayDataSource(MtomTestHelper.requestJpeg, "image/jpeg")));

    }
    
});

// process response 

CxfPayload<SoapHeader> out = exchange.getOut().getBody(CxfPayload.class);
Assert.assertEquals(1, out.getBody().size());

Map<String, String> ns = new HashMap<String, String>();
ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS);
ns.put("xop", MtomTestHelper.XOP_NS);

XPathUtils xu = new XPathUtils(ns);
Element oute = new XmlConverter().toDOMElement(out.getBody().get(0));
Element ele = (Element)xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", oute,
                                   XPathConstants.NODE);
String photoId = ele.getAttribute("href").substring(4); // skip "cid:"

ele = (Element)xu.getValue("//ns:DetailResponse/ns:image/xop:Include", oute,
                                   XPathConstants.NODE);
String imageId = ele.getAttribute("href").substring(4); // skip "cid:"

DataHandler dr = exchange.getOut().getAttachment(photoId);
Assert.assertEquals("application/octet-stream", dr.getContentType());
MtomTestHelper.assertEquals(MtomTestHelper.RESP_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream()));
   
dr = exchange.getOut().getAttachment(imageId);
Assert.assertEquals("image/jpeg", dr.getContentType());

BufferedImage image = ImageIO.read(dr.getInputStream());
Assert.assertEquals(560, image.getWidth());
Assert.assertEquals(300, image.getHeight());
Copy to Clipboard Toggle word wrap
Payload モードで CXF エンドポイントから受信した Camel メッセージを使用することもできます。
public static class MyProcessor implements Processor {

    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        CxfPayload<SoapHeader> in = exchange.getIn().getBody(CxfPayload.class);
        
        // verify request
        assertEquals(1, in.getBody().size());
        
        Map<String, String> ns = new HashMap<String, String>();
        ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS);
        ns.put("xop", MtomTestHelper.XOP_NS);

        XPathUtils xu = new XPathUtils(ns);
        Element body = new XmlConverter().toDOMElement(in.getBody().get(0));
        Element ele = (Element)xu.getValue("//ns:Detail/ns:photo/xop:Include", body,
                                           XPathConstants.NODE);
        String photoId = ele.getAttribute("href").substring(4); // skip "cid:"
        assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId);
        
        ele = (Element)xu.getValue("//ns:Detail/ns:image/xop:Include", body,
                                           XPathConstants.NODE);
        String imageId = ele.getAttribute("href").substring(4); // skip "cid:"
        assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId);

        DataHandler dr = exchange.getIn().getAttachment(photoId);
        assertEquals("application/octet-stream", dr.getContentType());
        MtomTestHelper.assertEquals(MtomTestHelper.REQ_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream()));
   
        dr = exchange.getIn().getAttachment(imageId);
        assertEquals("image/jpeg", dr.getContentType());
        MtomTestHelper.assertEquals(MtomTestHelper.requestJpeg, IOUtils.readBytesFromStream(dr.getInputStream()));

        // create response
        List&lt;Source> elements = new ArrayList&lt;Source>();
        elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement()));
        CxfPayload&lt;SoapHeader> sbody = new CxfPayload&lt;SoapHeader>(new ArrayList&lt;SoapHeader>(),
            elements, null);
        exchange.getOut().setBody(sbody);
        exchange.getOut().addAttachment(MtomTestHelper.RESP_PHOTO_CID, 
            new DataHandler(new ByteArrayDataSource(MtomTestHelper.RESP_PHOTO_DATA, "application/octet-stream")));

        exchange.getOut().addAttachment(MtomTestHelper.RESP_IMAGE_CID, 
            new DataHandler(new ByteArrayDataSource(MtomTestHelper.responseJpeg, "image/jpeg")));

    }
}
Copy to Clipboard Toggle word wrap
メッセージモード: 添付ファイルはメッセージをまったく処理しないため、サポートされていません。
CXF_MESSAGE モード: MTOM はサポートされ、添付ファイルは上記の Camel Message API で取得できます。マルチパート(つまり MTOM)メッセージを受信すると、デフォルトの SOAPMessage から String コンバーターは、ボディーの完全なマルチパートペイロードを提供することに注意してください。SOAP XML を String として要求する場合は、message.getSOAPPart() でメッセージボディーを設定し、Camel 変換で残りの作業を行うことができます。

スタックトレース情報を伝播させる方法

Java の例外がサーバー側で発生したときに、例外のスタックトレースがフォールトメッセージにマーシャリングされてクライアントに返されるように、CXF エンドポイントを設定することができます。この機能を有効にするには、dataFormatPAYLOAD に設定し、以下のように faultStackTraceEnabled プロパティーを true に設定します。cxfEndpoint
<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage"
    wsdlURL="ship.wsdl"
    endpointName="s:TestSoapEndpoint"
    serviceName="s:TestService"
    xmlns:s="http://test">
  <cxf:properties>
    <!-- enable sending the stack trace back to client; the default value is false-->
    <entry key="faultStackTraceEnabled" value="true" />
    <entry key="dataFormat" value="PAYLOAD" />
  </cxf:properties>
</cxf:cxfEndpoint>
Copy to Clipboard Toggle word wrap
セキュリティー上の理由から、スタックトレースには原因となる例外(つまり、Caused byに続くスタックトレースの一部)は含まれません。スタックトレースに原因となる例外を含める場合は、以下のように cxfEndpoint 要素で exceptionMessageCauseEnabled プロパティーを true に設定します。
<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage"
    wsdlURL="ship.wsdl"
    endpointName="s:TestSoapEndpoint"
    serviceName="s:TestService"
    xmlns:s="http://test">
  <cxf:properties>
    <!-- enable to show the cause exception message and the default value is false -->
 <entry key="exceptionMessageCauseEnabled" value="true" />
    <!-- enable to send the stack trace back to client,  the default value is false-->
    <entry key="faultStackTraceEnabled" value="true" />
    <entry key="dataFormat" value="PAYLOAD" />
  </cxf:properties>
</cxf:cxfEndpoint>
Copy to Clipboard Toggle word wrap
警告
exceptionMessageCauseEnabled フラグは、テストおよび診断の目的でのみ有効にする必要があります。サーバーにおいて例外の元の原因を隠すことで、敵対的なユーザーがサーバーを調査しにくくするのが、通常の実践的なやり方です。

PAYLOAD モードのストリーミングサポート

2.8.2 では、PAYLOAD モードを使用する場合に camel-cxf コンポーネントで受信メッセージのストリーミングがサポートされるようになりました。以前は、受信メッセージは完全に DOM 解析されていました。メッセージが大きい場合、これには時間がかかり、大量のメモリーを使用します。2.8.2 以降、受信メッセージはルーティング時に javax.xml.transform.Source として残ることができます。また、ペイロードを何も変更しないと、ターゲットの宛先に直接ストリーミングできます。一般的な単純なプロキシーのユースケース(例:from ("cxf:..").to ("cxf:..."))では、パフォーマンスが大幅に向上し、メモリー要件が大幅に低下する可能性があります。
ただし、ストリーミングが適切でない、または望ましくない場合もあります。ストリーミングの性質上、無効な受信 XML は処理チェーンで後でキャッチされないことがあります。また、特定のアクションでは、メッセージを DOM で解析する必要があります(WS-Security やメッセージトレースなど)。この場合、ストリーミングの利点は制限されます。この時点で、ストリーミングを制御する方法は 2 つあります。
  • endpoint プロパティー:"allowStreaming=false" をエンドポイントプロパティーとして追加し、ストリーミングをオン/オフにすることができます。
  • Component プロパティー:CxfComponent オブジェクトには、そのコンポーネントから作成されたエンドポイントのデフォルトを設定できる allowStreaming プロパティーもあります。
  • グローバルシステムプロパティー:org.apache.camel.component.cxf.streaming のシステムプロパティーを false に追加して、オフにできます。これにより、グローバルのデフォルトが設定されますが、上記の endpoint プロパティーを設定すると、そのエンドポイントに対してこの値が上書きされます。

汎用 CXF ディスパッチモードの使用

2.8.0 以降、camel-cxf コンポーネントは汎用 CXF ディスパッチモード をサポートします。これは、任意の構造のメッセージを転送できます(つまり、特定の XML スキーマにバインドされていません)。このモードを使用するには、CXF エンドポイントの wsdlURL および serviceClass 属性の指定を省略します。
<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/SoapContext/SoapAnyPort">
  <cxf:properties>
    <entry key="dataFormat" value="PAYLOAD"/>
  </cxf:properties>
</cxf:cxfEndpoint>
Copy to Clipboard Toggle word wrap
デフォルトの CXF ディスパッチクライアントは特定の SOAPAction ヘッダーを送信しません。そのため、ターゲットサービスが特定の SOAPAction 値を必要とする場合、キー SOAPAction (大文字小文字の区別なし)を使用して Camel ヘッダーに提供されます。
トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2025 Red Hat