Hello,
I should have mentioned, that replacing these two lines (following the
mentioned documentation) in my implementation:
SOAPElement sUsersElement =
ObjectSerializer.toSOAPElement( sUsers, AGConstants.AG_SERVICEUSERS );
AnyHelper.setAny(context, sUsersElement);
with these two lines:
Element e =
ObjectSerializer.toElement(sUsers, AGConstants.AG_SERVICEUSERS);
context.set_any(new MessageElement[] { new MessageElement(e) });
seems to fix the problem.
Best regards,
Dominic
Dominic Battre wrote:
Hello,
I think I have found an error in either the ObjectSerializer/AnyHelper
implementation or the way the documentation suggests to use them. I'd
like to hear your opinion, whether this is my fault or whether I should
file a bug report.
Problem description
===================
I need to serialize objects as AnyTypes and retrieve them later. This
works for trivial types but not complex types.
Let's have a look the documentation that can be found here:
http://www.globus.org/toolkit/docs/development/4.1.1/common/javawscore/developer/index.html
You can find this example source code (section 5.2.1.2. Working with
AnyContentType content):
// convert Java object into SOAPElement
EndpointReferenceType object = ...;
QName elementName = new QName("http://example.com", "EPR");
SOAPElement element = ObjectSerializer.toSOAPElement(object,
elementName);
// set the SOAPlement as Any content
AnyContentType bean = ...;
AnyHelper.setAny(bean, element);
To make it more concrete, I have filled the blanks:
EndpointReferenceType object = new EndpointReferenceType();
// the following line is new
object.setAddress(new AttributedURI("https://foo.bar.com/service"));
QName elementName = new QName("http://example.com", "EPR");
SOAPElement element = ObjectSerializer.toSOAPElement(object,
elementName);
System.out.println(element);
Note that I specify an Address in the EPR (contrary to the example
code). This is the output of the println statement:
(formating done by myself)
<ns1:EPR xsi:type="ns2:EndpointReferenceType"
xmlns:ns1="http://example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns2="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<Address xsi:type="xsd:anyURI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
https://foo.bar.com/service
</Address>
<ReferenceProperties xsi:type="ns2:ReferencePropertiesType"/>
<ReferenceParameters xsi:type="ns2:ReferenceParametersType"/>
<PortType xsi:type="ns2:AttributedQName" xsi:nil="true"/>
<ServiceName xsi:type="ns2:ServiceNameType" xsi:nil="true"/>
</ns1:EPR>
Note that all elements beneath /ns1:EPR do not have namespaces.
If I deserialize this again:
String xml = element.toString();
EndpointReferenceType epr = (EndpointReferenceType)
ObjectDeserializer.deserialize(
new InputSource(new StringReader(xml) ),
EndpointReferenceType.class);
System.out.println("Address = " + epr.getAddress());
System.out.println("Any = " + AnyHelper.toSingleString(epr.get_any()));
The address is empty and all attributes are stored in epr.get_any().
Address = null
Any = <Address xsi:type="xsd:anyURI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">https://foo.bar.com/service</Address><ReferenceProperties
xsi:type="ns2:ReferencePropertiesType"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<ReferenceParameters xsi:type="ns2:ReferenceParametersType"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<PortType xsi:type="ns2:AttributedQName" xsi:nil="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<ServiceName xsi:type="ns2:ServiceNameType" xsi:nil="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
The deserializer cannot parse the XML code correctly because the
namespaces are missing. Note that the same problem occurs if I don't
serialize with element.toString() but store the element as in the
example: AnyHelper.setAny(bean, element);
If I used a different datatype than EndpointReferenceType without an
<xs:any/>* I'd have received an exception.
Problem Analysis
================
The problem is the ObjectSerializer.toSOAPElement(object, elementName);
call. During the serialization, Axis checks in BeanSerializer.java:147
serialize(QName, Attributes, Object, SerializationContext), whether it
serializes to a SOAP Context and drops the namespaces:
// If we're SOAP encoded, just use the local part,
// not the namespace. Otherwise use the whole
// QName.
if (isEncoded) {
qname = new QName(element.getXmlName().getLocalPart());
} else {
qname = element.getXmlName();
}
This is the reason, why all nested objects are serialized without
namespaces.
Question
========
My question is now:
Who is to blame?
1) Me
2) Axis
3) ObjectSerializer or AnyHelper
4) the Globus documentation
Should I file a bug? If yes, to which component.
Thanks for your help,
Dominic