You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Marian Muller <ma...@serli.com> on 2010/11/16 17:21:11 UTC

Re-sending a request in a client-side inbound interceptor

Hello,

I am trying to create a client-side interceptor which would send a forged
SOAP request while processing a response.
Let me give an example.

My WebService client sends a request to an endpoint.
The endpoint does some processing and return a response.
The response is processed by the client interceptor:
* if the response is what we expected, just process it normally
* if the response contains some specific info, forge a new request, send it
and use its response.

I managed to detect the "specific info" and forge the corresponding new
request. Now, to send this request and use its response instead of the first
response (the one being processed), I use the following code in the
client-side inbound interceptor:

            SOAPMessage request = // Get the forged request as a SOAPMessage

                  // Store the original response
            Message origResponse = this.currentMessage;


            // SEND THE REQUEST //

            // Copy the original request parameters
            List params =
origResponse.getExchange().getOutMessage().getContent(List.class);

            // Forge CXF request Message from the given SOAPMessage
            Endpoint ep = origResponse.getExchange().get(Endpoint.class);
            Message requestMsg = ep.getBinding().createMessage();
            requestMsg.setContent(List.class, params);
            requestMsg.setContent(SOAPMessage.class, request);

            // Set message environment
            requestMsg.setExchange(origResponse.getExchange());
            requestMsg.getExchange().setOutMessage(requestMsg);

            // Set output interceptor chain
            InterceptorChain chain = OutgoingChainInterceptor
                    .getOutInterceptorChain(origResponse.getExchange());
            requestMsg.setInterceptorChain(chain);

            // Set the "requestor" flag so that service knows we are
requesting
            requestMsg.put(org.apache.cxf.message.Message.REQUESTOR_ROLE,
true);

            // Send the request
            chain.doIntercept(requestMsg);

            // Response to this request is treated in its own client-side
            // inbound interceptor chain


            // GET THE RESPONSE //
            // Copy the new response into the original response

            // Get the new response (i.e. response to the request we just
sent)
            Message responseMsg = requestMsg.getExchange().getInMessage();

            // Copy contents
            Class<?>[] formats = responseMsg.getContentFormats().toArray(new
Class<?>[0]);
            if (formats != null) {
                for (Class<?> format : formats) {
                    origResponse.setContent(format,
responseMsg.getContent(format));
                }
            }
            // Copy attachments
            origResponse.setAttachments(responseMsg.getAttachments());

            // Stop the current chain because the new response has already
been
            // processed by its own chain ; just use the new response as-is
to
            // extract the result
            origResponse.getInterceptorChain().pause();


Could you please confirm (or not) that this is the way to do it ? Will this
work in every cases (including those I haven't met yet, obviously) ? Or what
should I do instead ?
Is there also an easier/cleaner way to do this ? Maybe this has already been
done somewhere ?

Thanks.
--
Marian MULLER
SERLI