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



Reply via email to