An issue was raised by the RI team about how to bind SOAP headers to parameters when there is more
than one SOAP header of a particular type.
As described in "2.6.2.1 Header Binding Extension" of the early draft, binding of SOAP headers to a
parameter can occur when:
- a part from the main message is bound to a SOAP header in the WSDL binding
- mapping of additional parts (from a different message) bound to a header is enabled.
WS-I BP states that the order of headers in a SOAP message is independent of the order of soap:header
elements in the WSDL binding – see R2751 in WS-I Basic Profile 1.0. The question is how to determine
which header should be bound to which parameter.
For example consider the following WSDL description:
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://example.com/headerbinding"
xmlns:tns="http://example.com/headerbinding"
xmlns:types="http://example.com/headerbinding">
wsdl:types
<xsd:schema targetNamespace="http://example.com/headerbinding"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="ClaimDetail" type="types:ClaimDetailType"/>
<xsd:complexType name="ClaimDetailType">
xsd:sequence
<xsd:element name="Name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Address" type="types:AddressType"/>
<xsd:complexType name="AddressType">
xsd:sequence
<xsd:element name="Street" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="ClaimRefNo" type="xsd:string"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ClaimIn">
<wsdl:part name="claimDetails" element="types:ClaimDetail"/>
<wsdl:part name="homeAddress" element="types:Address"/>
<wsdl:part name="workAddress" element="types:Address"/>
</wsdl:message>
<wsdl:message name="ClaimOut">
<wsdl:part name="out" element="types:ClaimRefNo"/>
</wsdl:message>
<wsdl:portType name="ClaimPortType">
<wsdl:operation name="SubmitClaim">
<wsdl:input message="tns:ClaimIn"/>
<wsdl:output message="tns:ClaimOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ClaimBinding" type="tns:ClaimPortType">
<soapbind:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="SubmitClaim">
<soapbind:operation soapAction="http://example.com/soapaction"/>
wsdl:input
<soapbind:body parts="claimDetail" use="literal"/>
<soapbind:header message="tns:ClaimIn"
part="homeAddress" use="literal"/>
<soapbind:header message="tns:ClaimIn"
part="workAddress" use="literal"/>
</wsdl:input>
wsdl:output
<soapbind:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>
Resulting input message for "SubmitClaim" document/literal operation:
<env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:types="http://example.com/headerbinding">
env:Header
types:Address
...
</types:Address>
types:Address
...
</types:Address>
</env:Header>
env:Body
types:ClaimDetail
...
</types:SubmitClaim>
</env:Body>
</env:Envelope>
Desired Java SEI
public interface ClaimPortType {
public String submitClaim(ClaimDetail detail, Address homeAddress, Address workAddress);
}
public class ClaimDetail {
// JAXB generated class for ClaimDetail element
public ClaimDetail();
public String getName();
public void setName(String name);
...
}
public class Address {
// JAXB generated class for Address element
public Address();
public String getStreet();
public void setStreet(String street);
...
}
Note that there's no way at runtime to tell the difference between the Address element for home
address and the Address element for work address. I can see a number of approaches:
Assume lexical order is significant (against R2751) and bind the first Address element to
homeAddress and the second to workAddress.
PRO: Simple solution
CON: Interop problems likely
(ii) Require JAX-RPC impls to flag this as an error during WSDL->Java mapping.
PRO: Will prevent the problem for declared headers
CON: More work for JAX-RPC impls, doesn't handle the case when additional undeclared headers are
present that are identical to those declared in the WSDL (see R2739)
(iii) Require JAX-RPC impls to flag this as an error during WSDL->Java mapping and to flag a runtime
error when trying to bind a header that is not unique.
PRO: Prevents the problem for declared and undeclared headers
CON: More work for JAX-RPC impls, may cause problems in systems where multiple identical headers
can be present in the message (possible to alleviate this with a handler though)
(iv) Remove support for binding of headers to method parameters.
PRO: Simple solution
CON: Binding impacts WSDL->Java mapping (parts in the main message can be bound to headers, the
body or attachments), binding headers is a simple solution compared to instantiating a hander.
Environment
Operating System: All
Platform: All
Affected Versions
[current]