8

どの操作が呼び出されているかに基づいて異なるコードを実行する受信メッセージ用のカスタム SOAP メッセージ ハンドラーがあります。操作名を取得する最初の試みは、次のようになりました。

public boolean handleMessage(SOAPMessageContext context)
{
    String op = context.get(MessageContext.WSDL_OPERATION);
    ...

プロパティが設定されていないように見えるため、これは失敗しましたMessageContext.WSDL_OPERATION。次に、これを使用してみました:

public boolean handleMessage(SOAPMessageContext context)
{
    Map<?, ?> headers = (Map<?, ?>)context.get(MessageContext.HTTP_REQUEST_HEADERS);    
    ArrayList<String> SOAPAction = ((ArrayList<String>) headers.get("SOAPAction"));
    String opName = SOAPAction.get(0);
    //opName will be formatted like "urn#myOperation", so the prefix must be removed
    opName = ((opName.replace("\"","").split("#"))[1]);

これは機能しますが、ヘッダー プロパティ「SOAPAction」が設定されていない (または存在すらしていない) か、期待する値を持っていない可能性があるのではないかと心配しています。これが操作名を取得する「公式」の方法であるかどうかわからないため、少し心配です-contextデバッガーの内容を見てわかりました。

着信 SOAP メッセージを処理するときに操作名を取得するより良い方法はありますか?

4

4 に答える 4

5

私はこのパーティーに非常に遅れていますが、私は先週これをやろうとしました. 受け入れられた答えは、実際にはすべての JAX-WS 実装で機能するとは限りません (少なくとも私が試したものではありません)。

私は、開発環境のスタンドアロン Metro でこれを機能させようとしていますが、実際の環境では WebSphere 7 にバンドルされている Axis2 も使用しています。

Metro で次の作品を見つけました。

String operationName = body.getChildNodes().item(0).getLocalName();

以下は Axis2 で機能します。

String operationName = body.getChildNodes().item(1).getLocalName();

Axis2 はタイプの Node をText最初の子として Body に挿入しますが、Metro は挿入しません。このテキスト ノードは、null ローカル名を返します。私の解決策は、次のことを行うことでした。

NodeList nodes = body.getChildNodes();

// -- Loop over the nodes in the body.
for (int i=0; i<nodes.getLength(); i++) {
  Node item = nodes.item(i);

  // -- The first node of type SOAPBodyElement will be
  // -- what we're after.
  if (item instanceof SOAPBodyElement) {
    return item.getLocalName();
  }
}

コメントで説明されているように、実際には type の最初のノードを探していますSOAPBodyElement。うまくいけば、それは将来これを見ている他の誰かに役立つでしょう.

于 2014-02-21T19:03:42.657 に答える
4

body.getElementName().getLocalName()メッセージペイロードのSOAP本文要素の名前を取得するために呼び出すことができます。少し冗長で手動ですが、機能します。ハンドラーに次のものを含めることができます

if ((boolean) context.get(MessageContext.MESSAGE_INBOUND_PROPERTY){ //for requests only
            SOAPEnvelope msg = context.getMessage().getSOAPPart().getEnvelope(); //get the SOAP Message envelope
                SOAPBody body = msg.getBody();
            String operationName = body.getChildNodes().item(1).getLocalName();
}

上記のコードの結果は、WSDLで指定された操作の名前を保持することが保証されています

編集:このソリューションは、Webサービスがドキュメント/リテラル​​ラップまたはRPC/リテラル​​として実装されているという条件のみに基づいています

于 2012-11-24T16:42:44.913 に答える
3

SOAPMessageContext にはこの情報が含まれており、次のように非常に簡単に取得できます。

public boolean handleMessage(SOAPMessageContext msgContext) {
    QName svcn = (QName) smc.get(SOAPMessageContext.WSDL_SERVICE);      
    QName opn = (QName) smc.get(SOAPMessageContext.WSDL_OPERATION);
    System.out.prinln("WSDL Service="+ svcn.getLocalPart());
    System.out.prinln("WSDL Operation="+ opn.getLocalPart());

    return true;
}
于 2013-05-16T17:22:47.243 に答える