2

WS-Addressing SOAP ヘッダーを必要とする Web サービスを呼び出しています。CXF で Apache Camel を使用して Web サービスを呼び出しています。Web サービスの WSDL を使用して CXF エンドポイントを構成すると、WS-Adressing SOAP ヘッダーが自動的に追加されますが、カスタム MessageId を設定する必要があります。

現在送信中のメッセージは次のとおりです。

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <soap:Header>
        <ws:international xmlns:ws="http://www.w3.org/2005/09/ws-i18n">
            <ws:locale xmlns:ws="http://www.w3.org/2005/09/ws-i18n">en_CA</ws:locale>
        </ws:international>
        <fram:user wsa:IsReferenceParameter="true" xmlns:fram="http://wsbo.webservice.ephs.pdc.ibm.com/Framework/" xmlns:wsa="http://www.w3.org/2005/08/addressing">BESTSystem</fram:user>
        <Action soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">http://webservice.ephs.pdc.ibm.com/Client/QueryHumanSubjects</Action>
        <MessageID soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:945cfd10-9fd2-48f9-80b4-ac1b9f3293c6</MessageID>
        <To soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">https://panweb5.panorama.gov.bc.ca:8081/ClientWebServicesWeb/ClientProvider</To>
        <ReplyTo soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">
            <Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
        </ReplyTo>
    </soap:Header>
    <soap:Body>
        <ns2:queryHumanSubjectsRequest xmlns:ns2="http://wsbo.webservice.ephs.pdc.ibm.com/Client/" xmlns:ns3="http://wsbo.webservice.ephs.pdc.ibm.com/FamilyHealth/">
            <!-- stuff -->
        </ns2:queryHumanSubjectsRequest>
    </soap:Body>
</soap:Envelope>

ご覧のとおり、MessageId の値は「urn:uuid:945cfd10-9fd2-48f9-80b4-ac1b9f3293c6」です。カスタム値を設定する必要があります。

「国際」や「ユーザー」などの他のヘッダーを追加する方法で MessageId ヘッダーを追加しようとしましたが、フレームワークの一部が値をオーバーライドします。

// Note this doesn't work! Something overrides the value. It works for other headers.
@Override
public void process(Exchange exchange) throws Exception {

    Message in = exchange.getIn();
    List<SoapHeader> headers = CastUtils.cast((List<?>) in.getHeader(Header.HEADER_LIST));

    SOAPFactory sf = SOAPFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    QName MESSAGE_ID_HEADER = new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa");
    SOAPElement messageId = sf.createElement(MESSAGE_ID_HEADER);
    messageId.setTextContent("customValue");
    SoapHeader soapHeader = new SoapHeader(MESSAGE_ID_HEADER, messageId);
    headers.add(soapHeader);
}

CXF Web サイトには、WS-Addressing ヘッダーの設定方法に関するドキュメントがいくつかありますが、それを Apache Camel に適用する方法がわかりません。Apache Camel CXFのドキュメントでも、WS-Addressing について特に言及していません。

4

2 に答える 2

1

投稿したドキュメント リンクには実際に必要な情報が含まれていますが、Camel に適用する方法はすぐにはわかりません。

CXF のドキュメントには、次のように記載されています。

CXF org.apache.cxf.ws.addressing.impl.AddressingPropertiesImpl オブジェクトを使用して、Reply-To を含む WS-Addressing の多くの側面を制御できます。

AddressingProperties maps = new AddressingPropertiesImpl();
EndpointReferenceType ref = new EndpointReferenceType();
AttributedURIType add = new AttributedURIType();
add.setValue("http://localhost:9090/decoupled_endpoint");
ref.setAddress(add);
maps.setReplyTo(ref);
maps.setFaultTo(ref);
((BindingProvider)port).getRequestContext()
        .put("javax.xml.ws.addressing.context", maps);

「RequestContext」でアドレス指定プロパティを設定することに注意してください。

Apache Camel のドキュメントには、次のように書かれています。

camel-cxf エンドポイントのリクエストとレスポンスのコンテキストを伝播する方法

CXF クライアント API は、要求と応答のコンテキストで操作を呼び出す方法を提供します。camel-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);
    }
});

上記の例には必要のないものが含まれていますが、重要なことは、CXF リクエスト コンテキストの設定方法を示していることです。

それらをまとめると、次のようになります。

@Override
public void process(Exchange exchange) throws Exception {
    AttributedURIType messageIDAttr = new AttributedURIType();
    messageIDAttr.setValue("customValue");

    AddressingProperties maps = new AddressingProperties();
    maps.setMessageID(messageIDAttr);

    Map<String, Object> requestContext = new HashMap<>();
    requestContext.put(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES, maps);
    exchange.getIn().setHeader(Client.REQUEST_CONTEXT, requestContext);
}

// org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES = "javax.xml.ws.addressing.context"
// org.apache.cxf.endpoint.Client.REQUEST_CONTEXT = "RequestContext"


警告: 私のルートでは、複数の異なる Web サービスを順番に呼び出しています。上記のように RequestContext を設定した後、Camel がすべての Web サービスに対して同じ RequestContext を使用し始めたことがわかりました。その結果、「メッセージ アドレス指定プロパティを表すヘッダーが無効であり、メッセージを処理できません」というエラーが発生しました。これは、最初の呼び出し以降のすべての Web サービス呼び出しで、正しくない "Action" ヘッダーが使用されたためです。

これを、設定したヘッダーとは別に、「RequestContext」 Exchange プロパティを使用して Apache Camel までさかのぼりました。これは明らかにヘッダーよりも優先されます。後続の Web サービスを呼び出す前にこのプロパティを削除すると、CXF は正しい Action ヘッダーを自動的に入力します。

于 2019-01-09T17:05:04.533 に答える