5

エンドポイントに送信される前にSoapメッセージの内容を変更するWebサービスのインターセプターを作成しようとしています。クライアントが要素の値が1のメッセージを送信した場合、その要素を2に変更して、メッセージがエンドポイントに到着したときに、クライアントが2ではなく2を送信したように見せたいと思います。 1.これが私を惑わすような難しい仕事なのか、それとも私が必要以上に難しくしている簡単な仕事なのかはわかりません。

Springインターセプターのいくつかをステップスルーしました。ただし、検証およびロギングインターセプターは、転送中のメッセージをすべて変更するわけではありません。Wss4jSecurityInterceptorは、MessageContextにいくつかのプロパティを追加します。しかし、私はそれがしていることを何も活用することができませんでした。私は迎撃機のシェルを持っています。しかし、何か価値のあることをしているものは何もありません。

public boolean handleRequest(MessageContext messageContext, Object endpoint)
        throws Exception {

    SaajSoapMessage saajSoapMessage = (SaajSoapMessage) messageContext
            .getRequest();
    SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
    SOAPBody soapBody = soapMessage.getSOAPBody();

    return true;
}

私は、他の誰かがこの特定の問題をすでに解決している可能性があることを望んでいました。任意の洞察をいただければ幸いです。ありがとう。

4

3 に答える 3

6

ペイロードの変更は少し注意が必要です。この作業を行うために私が見つけた唯一の方法は、データを操作するための使いやすいオブジェクトを公開する、のメソッドgetPayloadSource()getPayloadResult()メソッドを使用することです。SoapBodyjavax.xml.transform

それは厄介なヘビー級ですが、あなたはこのようなことをすることができます:

Transformer identityTransform = TransformerFactory.newInstance().newTransformer();
DOMResult domResult = new DOMResult();
identityTransform.transform(soapBody.getPayloadSource(), domResult);

Node bodyContent = domResult.getNode(); // modify this

identityTransform.transform(new DOMSource(bodyContent), soapBody.getPayloadResult());

これを行うためのより良い方法を見てみたいです。

于 2010-07-22T21:15:38.243 に答える
1

後でリクエストを変更する方が簡単だと気づきました。エンドポイントに到達する前にデータを変更できる限り、元のSOAPメッセージを変更する必要はありませんでした。

私が使用しているエンドポイントはすべてAbstractDom4jPayloadEndpointを拡張します。そのため、これらのエンドポイントをプロキシでラップして、エンドポイントに進む前にリクエスト要素を変更できるようにしました。すなわち:

public class MyProxyEndpoint extends AbstractDom4jPayloadEndpoint

    @Override
    protected Element invokeInternal( 
        Element requestElement,
        Document responseDocument ) throws Exception
    {
        if( requestElement != null )
        {
            // alter request element
        }

        return ( Element ) this.invokeMethod.invoke( 
            this.target,
            requestElement,
            responseDocument );
    }
于 2010-07-28T18:03:29.913 に答える
1

この回答のコードを変更して、<authentication/>すべてのSOAP本文リクエストに要素を挿入しました。

@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
    logger.trace("Enter handleMessage");
    try {
        SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
        addAuthn(request);
    } catch (Exception e) {
        logger.error(e.getMessage(),e);
    }

    return true;
}

protected void addAuthn(SaajSoapMessage request) throws TransformerException {
    Transformer identityTransform = TransformerFactory.newInstance().newTransformer();
    DOMResult domResult = new DOMResult();
    identityTransform.transform(request.getPayloadSource(), domResult);

    Node bodyContent = domResult.getNode();
    Document doc = (Document) bodyContent;
    doc.getFirstChild().appendChild(authNode(doc));

    identityTransform.transform(new DOMSource(bodyContent), request.getPayloadResult());
}

protected Node authNode(Document doc) {
    Element authentication = doc.createElementNS(ns, "authentication");
    Element username = doc.createElementNS(ns, "username");
    username.setTextContent(authn.getUsername());
    Element password = doc.createElementNS(ns, "password");
    password.setTextContent(authn.getPassword());
    authentication.appendChild(username);
    authentication.appendChild(password);
    return authentication;
}

このソリューションが使用されたのは、WebServiceMessageCallbackでドキュメントを変更する必要があり、構成済みのJaxb2Marshallerによってsoap本体が挿入される前にSaajSoapMessageFactoryがアクティブ化されるためです。

于 2016-11-13T14:15:34.517 に答える