You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Gary Gregory <ga...@gmail.com> on 2015/04/21 03:50:49 UTC

Calling org.apache.cxf.endpoint.Client with SOAP header values

Hi All:

We have an app server that uses org.apache.cxf.endpoint.Client to call
various third party services.

We are now dealing with a new WSDL which requires an element and child
element in the SOAP header for each invocation (a session header element
and a sesssion ID child element).

The SOAP has to look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:app.example.com">
   <soapenv:Header>
      <urn:SessionHeader>
         <urn:sessionId>ABC-Session-ID-XYZ</urn:sessionId>
      </urn:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <urn:SomeName/>
      ...
   </soapenv:Body>
</soapenv:Envelope>

This FAQ item is a helpful start:
http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest/response
?

Because our services are dynamic, I do not know at development time what
the header name or structure is, so I need to fetch it out of CXF's model
and create the SOAP headers programatically based on our server's input
which has its own object model.

I create a Client out a WSDL and a JaxWsDynamicClientFactory. Then I can do:

        final Endpoint endpoint = client.getEndpoint();
        final BindingInfo binding = endpoint.getBinding().getBindingInfo();
        final BindingOperationInfo boi = binding.getOperation(new
QName(namespace, bindingOperation));
        final BindingMessageInfo inputMessageInfo = boi.getInput();
        final List<MessagePartInfo> parts =
inputMessageInfo.getMessageParts();
        final MessagePartInfo partInfo = parts.get(0); // only one part.
        final Class<?> partClass = partInfo.getTypeClass();
        final Object[] operationArguments = buildArguments(..., partClass);
        List<Header> headers = new ArrayList<Header>();
        ...?...
        client.getRequestContext().put(Header.HEADER_LIST, headers);
        if (boi.isUnwrapped()) {
            result = client.invoke(bindingOperation, operationArguments);
        } else {
            result = client.invokeWrapped(bindingOperation,
operationArguments);
        }

How do I get the SOAP header part of the WSDL from CXF's model? In WSDL
it's the input's soap:header element:

  <operation name="SomeName">
   <soap:operation soapAction=""/>
   <input>
    <soap:header message="tns:Header" part="SessionHeader" use="literal"/>
    <soap:body use="literal" parts="parameters"/>
   </input>
   <output>
    <soap:body use="literal"/>
   </output>
  </operation>

It looks like I can get to all the other bits of the WSDL from
endpoint.getBinding().

Thoughts?

Thank you,
Gary

-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: Calling org.apache.cxf.endpoint.Client with SOAP header values

Posted by Gary Gregory <ga...@gmail.com>.
On Mon, Apr 20, 2015 at 6:56 PM, Gary Gregory <ga...@gmail.com>
wrote:

> I forgot to mention that I am on 2.7.15.
>
> Gary
>
> On Mon, Apr 20, 2015 at 6:50 PM, Gary Gregory <ga...@gmail.com>
> wrote:
>
>> Hi All:
>>
>> We have an app server that uses org.apache.cxf.endpoint.Client to call
>> various third party services.
>>
>> We are now dealing with a new WSDL which requires an element and child
>> element in the SOAP header for each invocation (a session header element
>> and a sesssion ID child element).
>>
>> The SOAP has to look like this:
>>
>> <soapenv:Envelope xmlns:soapenv="
>> http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:app.example.com
>> ">
>>    <soapenv:Header>
>>       <urn:SessionHeader>
>>          <urn:sessionId>ABC-Session-ID-XYZ</urn:sessionId>
>>       </urn:SessionHeader>
>>    </soapenv:Header>
>>    <soapenv:Body>
>>       <urn:SomeName/>
>>       ...
>>    </soapenv:Body>
>> </soapenv:Envelope>
>>
>> This FAQ item is a helpful start:
>> http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest/response
>> ?
>>
>> Because our services are dynamic, I do not know at development time what
>> the header name or structure is, so I need to fetch it out of CXF's model
>> and create the SOAP headers programatically based on our server's input
>> which has its own object model.
>>
>> I create a Client out a WSDL and a JaxWsDynamicClientFactory. Then I can
>> do:
>>
>>         final Endpoint endpoint = client.getEndpoint();
>>         final BindingInfo binding =
>> endpoint.getBinding().getBindingInfo();
>>         final BindingOperationInfo boi = binding.getOperation(new
>> QName(namespace, bindingOperation));
>>         final BindingMessageInfo inputMessageInfo = boi.getInput();
>>         final List<MessagePartInfo> parts =
>> inputMessageInfo.getMessageParts();
>>         final MessagePartInfo partInfo = parts.get(0); // only one part.
>>         final Class<?> partClass = partInfo.getTypeClass();
>>         final Object[] operationArguments = buildArguments(...,
>> partClass);
>>         List<Header> headers = new ArrayList<Header>();
>>         ...?...
>>         client.getRequestContext().put(Header.HEADER_LIST, headers);
>>         if (boi.isUnwrapped()) {
>>             result = client.invoke(bindingOperation, operationArguments);
>>         } else {
>>             result = client.invokeWrapped(bindingOperation,
>> operationArguments);
>>         }
>>
>> How do I get the SOAP header part of the WSDL from CXF's model? In WSDL
>> it's the input's soap:header element:
>>
>>   <operation name="SomeName">
>>    <soap:operation soapAction=""/>
>>    <input>
>>     <soap:header message="tns:Header" part="SessionHeader"
>> use="literal"/>
>>     <soap:body use="literal" parts="parameters"/>
>>    </input>
>>    <output>
>>     <soap:body use="literal"/>
>>    </output>
>>   </operation>
>>
>> It looks like I can get to all the other bits of the WSDL from
>> endpoint.getBinding().
>>
>
I found this:

inputMessageInfo.getExtensors(javax.wsdl.extensions.ExtensibilityElement.class)

Which gives me:

 (java.util.ArrayList<E>) [SOAPHeader ({
http://schemas.xmlsoap.org/wsdl/soap/}header):
required=null
message={urn:app.example.com}Header
part=SessionHeader
use=literal
soapHeaderFaults=[], SOAPBody ({http://schemas.xmlsoap.org/wsdl/soap/}body):
required=null
parts=[parameters]
use=literal, SOAPBody ({http://schemas.xmlsoap.org/wsdl/soap/}body):
required=null
parts=[parameters]
use=literal]

But I cannot seem to drill down to get the sessionID element.

Any ideas?

Thank you,
Gary



>> Thoughts?
>>
>> Thank you,
>> Gary
>>
>> --
>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>> Java Persistence with Hibernate, Second Edition
>> <http://www.manning.com/bauer3/>
>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>> Spring Batch in Action <http://www.manning.com/templier/>
>> Blog: http://garygregory.wordpress.com
>> Home: http://garygregory.com/
>> Tweet! http://twitter.com/GaryGregory
>>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: Calling org.apache.cxf.endpoint.Client with SOAP header values

Posted by Gary Gregory <ga...@gmail.com>.
I forgot to mention that I am on 2.7.15.

Gary

On Mon, Apr 20, 2015 at 6:50 PM, Gary Gregory <ga...@gmail.com>
wrote:

> Hi All:
>
> We have an app server that uses org.apache.cxf.endpoint.Client to call
> various third party services.
>
> We are now dealing with a new WSDL which requires an element and child
> element in the SOAP header for each invocation (a session header element
> and a sesssion ID child element).
>
> The SOAP has to look like this:
>
> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:urn="urn:app.example.com">
>    <soapenv:Header>
>       <urn:SessionHeader>
>          <urn:sessionId>ABC-Session-ID-XYZ</urn:sessionId>
>       </urn:SessionHeader>
>    </soapenv:Header>
>    <soapenv:Body>
>       <urn:SomeName/>
>       ...
>    </soapenv:Body>
> </soapenv:Envelope>
>
> This FAQ item is a helpful start:
> http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest/response
> ?
>
> Because our services are dynamic, I do not know at development time what
> the header name or structure is, so I need to fetch it out of CXF's model
> and create the SOAP headers programatically based on our server's input
> which has its own object model.
>
> I create a Client out a WSDL and a JaxWsDynamicClientFactory. Then I can
> do:
>
>         final Endpoint endpoint = client.getEndpoint();
>         final BindingInfo binding = endpoint.getBinding().getBindingInfo();
>         final BindingOperationInfo boi = binding.getOperation(new
> QName(namespace, bindingOperation));
>         final BindingMessageInfo inputMessageInfo = boi.getInput();
>         final List<MessagePartInfo> parts =
> inputMessageInfo.getMessageParts();
>         final MessagePartInfo partInfo = parts.get(0); // only one part.
>         final Class<?> partClass = partInfo.getTypeClass();
>         final Object[] operationArguments = buildArguments(..., partClass);
>         List<Header> headers = new ArrayList<Header>();
>         ...?...
>         client.getRequestContext().put(Header.HEADER_LIST, headers);
>         if (boi.isUnwrapped()) {
>             result = client.invoke(bindingOperation, operationArguments);
>         } else {
>             result = client.invokeWrapped(bindingOperation,
> operationArguments);
>         }
>
> How do I get the SOAP header part of the WSDL from CXF's model? In WSDL
> it's the input's soap:header element:
>
>   <operation name="SomeName">
>    <soap:operation soapAction=""/>
>    <input>
>     <soap:header message="tns:Header" part="SessionHeader" use="literal"/>
>     <soap:body use="literal" parts="parameters"/>
>    </input>
>    <output>
>     <soap:body use="literal"/>
>    </output>
>   </operation>
>
> It looks like I can get to all the other bits of the WSDL from
> endpoint.getBinding().
>
> Thoughts?
>
> Thank you,
> Gary
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory