I have a WSDL for a soap-based web service that contains a custom header:
<message name="Request">
<part element="common:Request" name="Request"></part>
<part element="common:myHeader" name="Header"></part>
</message>
<operation name="processRequest">
<soap:operation soapAction=""/>
<input>
<soap:body parts="Request" use="literal"/>
<soap:header message="tns:Request" part="Header" use="literal"></soap:header>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
The header type is defined in a separate schema file:
<xs:element name="myHeader" nillable="false" type="tns:myHeaderType"/>
<xs:complexType name="myHeaderType">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="JobID" type="tns:JobIDType" minOccurs="1" maxOccurs="1"/>
<xs:element name="TransactionID" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
Furthermore, I am validating against the definition of myHeaderType to make sure that the required elements are there, formatting constraints are met, etc. This all appears to be working correctly, in that well-formed requests are accepted and incorrectly formatted requests are rejected.
My problem arises with a consumer who uses Apache Axis (hidden behind a proprietary tool) to generate their web-service client. As described in another StackOverflow question here, Axis inserts some optional attributes on myHeader that are allowed by the SOAP standard (as nearly as I can tell):
<soapenv:Header>
<com:myHeader soapenv:mustUnderstand="0" soapenv:actor="">
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
<JobID>myJobId</JobID>
<TransactionID>myTransactionId</TransactionID>
</com:myHeader>
</soapenv:Header>
Because of the tool that my consumer is using, it is not feasible to modify the Axis-generated stubs to omit these attributes, as has been suggested elsewhere. Furthermore, it seems these attributes should be allowed by my service, if I'm going to claim to be a soap service. My question is, how can I modify my header definition to accommodate these optional attributes, and ideally plan for attributes that I might not be anticipating. Is there a standard type that I can extend for my header type definition, or a general best practice for this situation?
I was able to find a couple of solutions to my problem today. They both solve the problem, but I'm not confident in my judgement of which is really the better of the two, so I'll present them both here.
Both solutions center around modifying the definition of myHeaderType so that it can accommodate the unanticipated SOAP-defined attributes.
Within the SOAP WSDL schema definition (http://schemas.xmlsoap.org/wsdl/), there is a type called tExtensibleAttributesDocumented that includes the following very flexible attribute definition:
<xs:anyAttribute namespace="##other" processContents="lax"/>
By extending this abstract type, I was able to incorporate this liberal allowance for unanticipated attributes into my type. Here is the resulting code:
<xs:complexType name="myHeaderType">
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleAttributesDocumented">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="JobID" type="tns:JobIDType" minOccurs="1" maxOccurs="1"/>
<xs:element name="TransactionID" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Note that this does not check the contents of mustUnderstand or actor, and allows other attributes, including complete garbage, so long as it comes from a namespace that I have defined in my XML request.
The other alternative was to directly include the <xs:anyAttribute> in my type:
<xs:complexType name="myHeaderType">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="JobID" type="tns:JobIDType" minOccurs="1" maxOccurs="1"/>
<xs:element name="TransactionID" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
This has basically the same effect, as far as I was able to determine.
If there are any subtle differences between these solutions that I'm not aware of, I'd love to hear about it. If there is an accepted standard for this situation, I was not able to find it. Another weakness of this solution is that I was not able to get the attributes to validate against their definitions in the schema. Changing the processContents attribute to strict prevented even the well-defined mustUnderstand and actor attributes from being processed.
Yes, you can modify with Altova XMLSpy editor. Use functionally for 30 days.
Related
Using java 1.8, maven-jaxb2-plugin:0.14.0, and JAXB 2.3.0
when I generate java classes from XSD files, and some classes are too simple, JAXB decides to skip them. Instead, it puts a #XmlElementWrapper annotation.
Example:
<xs:complexType name="AAAA">
<xs:sequence>
<xs:element name="eeee" type="BBBB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
Turns into
#XmlElementWrapper(namespace = ...)
#XmlElement(namespace = ....)
protected List<BBBB> eeee;
in the logs, I see:
[INFO] Replacing field [eeee AAAA]
In this particular care this optimization does not help me, I would prefer to see the classes as I designed the XSD (eg. AAAA turned into a Java class).
Is there a way to force JAXB into generating all classes and stop running "Replacing field" step?
I'm not sure that I understand correctly. It will be better if you publicate full xsd model and original generated java class/expected class.
But, may be using refernce will help you
<xs:complexType name="AAAA">
<xs:sequence>
<xsd:element ref="eeee" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="eeee">
<xs:sequence>
<xs:element name="eeee" type="BBBB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
What are the conceptual and technical disadvantages of this request/response structure:
A)
<xs:element name="OrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="OrderID" type="xs:integer"/>
<xs:element name="OrderType" type="xs:integer"/>
<xsd:element name='OrderAttributes' type='xsd:string'/>
</xs:sequence>
</xs:complexType>
</xs:element>
where OrderAttributes element will contain string in the following XML structure:
<OrderName> xy </OrderName>
<OrderDate> xy </OrderDate>
<OrderDetails> xy </OrderDetails>
....lots of other attributes
compared to this request/response structure
B)
<xs:element name="OrderRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="OrderID" type="xs:integer"/>
<xs:element name="OrderType" type="xs:integer"/>
<xsd:element name="OrderAttributes">
<xs:complexType>
<xs:sequence>
<xs:element name="OrderName" type="xs:string"/>
<xs:element name="OrderDate" type="xs:date"/>
<xs:element name="OrderDetails" type="xs:string"/>
....lots of other attributes
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
I need to design web service interface for orders processing, and I am thinking about the two alternatives mentioned above.
Version A, is more generic, so interface doesn't need to change, when OrderAttributes structure changes in any way.
But schema validation is not possible.
And my question is, what are other disadvantages compared to version B. I am analyst, not programmer, so I cannot say, if there is some impact on parsing requests, generating code from contract etc...
First note that your generic use of the word attribute to refer to a property can be confusing in XML, where attribute refers to a specific construct that stands apart from element:
<element attribute="attribute value">
<childElement>child element value</childElement>
</element>
Then, while doing design, you might consider which properties you wish to represent as XML attribute and which you wish to represent as XML elements. See XML attribute vs XML element for help deciding.
Regarding your A vs B proposed designs, note that A simply is not viable -- you cannot have unescaped markup within an element declared to have xs:string content as you've shown. Furthermore, A would then require further parsing of the OrderAttributes contents anyway whereas B would leverage the XML parser to process OrderAttributes contents. (And, like you said, B would not leverage XSD validation either.)
For future expansion, consider instead the use of xs:any, which supports various interpretations of wildcard contents via its processContents attribute values of strict, lax, or skip.
I'm going to generate java code from the xsd. I want to know how to remove xsd element when converting xsd to java using jaxb. My goal is to ignore message
Ex:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="message"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Java Variables
#XmlElement
protected String name;
In here you can see that message element got removed. I want to know how to do that?
If I understand you correctly, to sum it up you want to ignore a mandatory element and still want the result to validate correctly. My short answer is that this is contradictory and does not make sense. JAXB is built to do it correctly and you want do it wrongly(?).
You have several options, eg.
Live with the extra constructor argument.
Generate no-arg constructor instead.
Don't generate, but hand code JAXB annotated classes. Maybe turn off some validation.
Don't use JAXB, use something else (dom4j et. al.) or handcraft the xml
Possibly you can add some overriding in a binding file or even a plug-in, but I wouldn't think it was worth it.
Can you alter the .xsd ?
The current Element "note" tells that both "name" and "message" are mandatory. If you want "message" to be conditional you probably need to add minOccurs="0" attribute:
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="message" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
I am in confusion as when to use SOAPBinding.ParameterStyle.BARE and SOAPBinding.ParameterStyle.WRAPPED .and which binding style is more preferred.what are the differences between them.
ParameterStyle.Bare and ParameterStyle.Wrapped affects your wsdl definitions of request and response messages only.
Lets take an example, we have a webservice with a method "test" which has 2 input "string1" and "string2" and it is returning a string as "rstring".
ParameterStyle.BARE
Your parameter's name will be visible as part name in your wsdl.
Request message:
<message name="test">
<part name="string1" element="tns:string1"/>
<part name="string2" element="tns:string2"/>
</message>
Response message:
<message name="testResponse">
<part name="rstring" element="tns:rstring"/>
</message>
In your xsd test and testResponse will be defined like below, and your wsdl element directly referring elements under test and test response from xsd.
<xs:complexType name="test">
<xs:sequence>
<xs:element name="string1" type="xs:string" minOccurs="0"/>
<xs:element name="string2" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:complexType name="testResponse">
<xs:sequence>
<xs:element name="rstring" type="xs:string" minOccurs="0"/>
</xs:sequence>
ParameterStyle.WRAPPED
In this style your request and response message will be wrapped in single input as "parameter" and output as "result". and they will refer that particular element in xsd for all elements within.
Request message:
<message name="test">
<part name="parameters" element="tns:test"/>
</message>
Response message:
<message name="testResponse">
<part name="result" element="tns:testResponse"/>
</message>
In your xsd test and testResponse will be defined as same as above,
<xs:complexType name="test">
<xs:sequence>
<xs:element name="string1" type="xs:string" minOccurs="0"/>
<xs:element name="string2" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:complexType name="testResponse">
<xs:sequence>
<xs:element name="rstring" type="xs:string" minOccurs="0"/>
</xs:sequence>
In above example , you can spot the difference. This is the only difference they implicate in wsdl.
Note: Above example is explained for Document type soap binding, in RPC, no xsd is involved so RPC.Bare is applicable only.
The document/literal wrapped style is the best approach and is also
the default. Wrapped document style with literal encoding has the
following advantages:
There is no type encoding info.
Everything that appears in the soap:body is defined by the Schema, so you can easily validate the message.
You have the method name in the soap message.
Document/literal is WS-I compliant, but without the WS-I restriction that the SOAP.body should have only one Child. The wrapped
pattern meets the WS-I restriction that the SOAP messages SOAP.body
has only one Child.
But in few cases you might have to use another style. If you have
overloaded operations, you cannot use the document/literal wrapped
style. WSDL allows overloaded operations, but when you add the wrapped
pattern to WSDL, you require an element to have the same name as the
operation, and you cannot have two elements with the same name in XML.
So you must use the document/literal, non-wrapped style or one of the
RPC styles.
Source: Which style of WSDL should I use?
I'm working with a set of schema descriptor files written by a third party. I need to generate JAXB stubs for them. Each XSD defines a different message type, along with a number of supporting simple and complex types. Many of the types are common to each XSD, but rather than factor them out into a separate XSD, the authors chose to define them in each namespace. This creates a grundle of namespace collisions when I try to compile the XSD's using xjc into a single package. I'm forced to separate them into unique packages. The problem is that this makes them non-interchangeable, when they should be. I have to do a lot of extra conversion to use data from one message type in a different message type.
My question: is there some way (binding customization?) I can instruct xjc to use one java class for each shared type, rather than unique classes spread across different packages?
Here's a simplified example. I've got two XSD's, one for an insert message and another for a response message. The response is meant to reference an insert message.
<!-- insert.xsd -->
<xs:schema
xmlns="msg.insert"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="msg.insert">
<xs:element name="Message" type="Message" />
<xs:complexType name="Message">
<xs:sequence>
<xs:element
maxOccurs="1"
minOccurs="1"
name="MessageId"
type="Identifier" />
<xs:element
maxOccurs="1"
minOccurs="1"
name="SequenceId"
type="Identifier" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Identifier">
<xs:sequence>
<xs:element
maxOccurs="1"
minOccurs="1"
name="ID"
type="xs:string" />
<xs:element
maxOccurs="1"
minOccurs="1"
name="Created"
type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Here's the second XSD...
<!-- response.xsd -->
<xs:schema
xmlns="msg.response"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="msg.response">
<xs:element name="Message" type="Message" />
<xs:complexType name="Message">
<xs:sequence>
<xs:element
maxOccurs="1"
minOccurs="1"
name="MessageId"
type="Identifier" />
<xs:element
maxOccurs="1"
minOccurs="1"
name="SequenceId"
type="Identifier" />
<xs:element
maxOccurs="1"
minOccurs="1"
name="ReferenceId"
type="Identifier" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Identifier">
<xs:sequence>
<xs:element
maxOccurs="1"
minOccurs="1"
name="ID"
type="xs:string" />
<xs:element
maxOccurs="1"
minOccurs="1"
name="Created"
type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
Note the Identifier complex type is identical in both schemas. It can and should be interchangeable between message types. But when I run xjc thus...
xjc -d java -p example.msg insert.xsd response.xsd
...I get collisions on the Message, Identifier, and ObjectFactory classes as follows.
[ERROR] A class/interface with the same name "example.msg.Message" is already in use. Use a class customization to resolve this conflict.
line 8 of insert.xsd
[ERROR] (Relevant to above error) another "Message" is generated from here.
line 8 of response.xsd
[ERROR] A class/interface with the same name "example.msg.Identifier" is already in use. Use a class customization to resolve this conflict.
line 15 of insert.xsd
[ERROR] (Relevant to above error) another "Identifier" is generated from here.
line 16 of response.xsd
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 8 of insert.xsd
[ERROR] (Related to above error) This is the other declaration.
line 8 of response.xsd
I completely understand why xjc is complaining, I'm trying to find a way to coax xjc into using a common class for the Identifier type, as well as resolve the collisions in the ObjectFactory class. One solution would be to factor the common types out into a separate namespace and reference them from each message type's XSD, but as mentioned these are all written by a third party and I don't have the ability to change them.
For now I'm compiling each XSD into a separate java package. This works but is very, very cumbersome.
The error output suggests there's a way to do this with a binding customization, but so far I haven't figured out how to make that work. Can anyone point me in the right direction?
you can solve this problem just by adding the following custom arg in the wsimport command:
-B-XautoNameResolution (without spaces)
This way, any name conflict will be automatically removed when parsing the xml.
Hope this helps
I had to deal with a similar issue to compile a huge library of XSD ( >1.8K XSD files) with a large rate of duplicated types between the XSDs.
The only feasible solution I've found was to generate an intermediate model with default packages per namespace, and process that afterward with Java codemodel moving all type classes into a single package, collapsing the duplicated classes.
Finally, I had to hack the marshaling to avoid namespace aware in the collapsed classes.
It seems like a crazy solution but worked just fine.
BTW -XautoNameResolution is just a way to automatically rename the duplicated type classes, but it does not solve the duplication issue.