function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
PNSPNS 

Serialization (marshaling/unmarshaling) to XML or JSON

Hi...

 

Has anyone implemented serialization of actual Salesforce data (i.e., records/rows returned as SObjects from the Web Services Java API) to XML or JSON?

 

Each such SObject has a getSerializer() method, but does this actually work in a generic way (i.e., so that any SObject records from a Salesforce table can be converted into, say, XML)?

 

I have tried numerous naive techniques (even resorted to JAXB and the Axis website), but nothing seems to do the job, so if there is any working example code, or documentation, I would be grateful.

 

Thanks!

dkadordkador

The message as sent over the wire in the SOAP API is already in XML format.  You're saying you want to use a SOAP framework to invoke the API, let it deserialize the SOAP response into a POJO, and then you want to serialize it back into an over-the-wire format such as XML or JSON?

 

Can't you just skip the SOAP framework part, or just tell your SOAP framework to not deserialize?

PNSPNS

Hi...

 

Actually, I use Axis 1.3 with the Force.com Web Services Partner API, which indeed deserializes each record of the SOAP response (from a Salesforce query), into a POJO (SObject). I need this deserialization anyway, in order to play with the actual data returned.

 

Not sure yet how I could get the SOAP response from the wire. All the calls I tried (even the getAsDocument() and getAsDOM() methods of each MessageElement object returned by the SObject get_any() method), did not help much.

 

The best I could get was the Namespace-enriched XML format from messageElement.getAsString(), which looks something like

 

 

<ns1:Id xmlns:ns1="urn:sobject.partner.soap.sforce.com">xxxxxxxxxxxxxxx</ns1:Id>

 for the Id field of a Salesforce table, while I am after the plain vanilla XML.

 

Getting to the XML format on the wire (how?) could help, but it would be even better if I could serialize the SObjects after some processing.

 

Any ideas?

 

Thanks!

 

 

 

PNSPNS

It seems that JAXB does not cooperate with Axis and eventually, in the absence of any other working solution, I had a look at the source code of Axis 1.3.

 

As I pointed out earlier on, SObject has a getSerializer() method, the return value of which is actually Serializer, but that is just an interface implemented by BeanSerializer and also the method's return statement is actually

 

return new org.apache.axis.encoding.ser.BeanSerializer(_javaType, _xmlType, typeDesc);

 

So, you can get a BeanSerializer object via Axis, as follows:

 

BeanSerializer serializer = (BeanSerializer)SObject.getSerializer(null, SObject.class, SObject.getTypeDesc().getXmlType());

 

Then, you can do a call like

 

serializer.serialize(name, attributes, object, context)

 

where

 

  • name = new QName(SObject.getTypeDesc().getXmlType().getLocalPart())
  • attributes = new AttributeImpl()
  • object is the SObject to be serialized 
  • context =  new SerializationContext(xmlOutput, new MessageContext(new AxisServer()))
  • xmlOutput = new StringWriter()

 

After serializer.serialize() is succesfully run, the serialized XML from the SObject is accessioble simply via

 

xmlOutput.toString()

 

Not exactly ideal (as it contains namespace tags etc., from the Namespace-enriched XML format I mentioned above), so it needs further processing). Otherwise, it does the job.

 

For deserialization, along the above lines, you can get a Deserializer object:

 

BeanDeserializer deserializer = (BeanDeserializer)SObject.getDeserializer(null, SObject.class, SObject.getTypeDesc().getXmlType());

 

From there, if you have the XML in a String variable called xml, a quick hack should look something like

 

DeserializationContext context = new DeserializationContext(
				 new InputSource(new StringReader(xml)),
				 new MessageContext(new AxisServer()),
				 SObject.getTypeDesc().getXmlType().toString());
context.parse();

// The deserializer.getValue(Object) call always returns null,
// so attempt the parameterless version
object = (SObject)deserializer.getValue();

 

However, this approach does not seem to work and can't bother to make it to, since I was mainly after serialization. Having said that, there are numerous possible deserializers in Axis, but this may not be an issue and BeanDeserializer should work for SObject anyway.

 

In the the post you suggested, people propose (apparently working) solutions for both serialization and deserialization, following a different approach. As for JSON, there is the Google Gson library (with an Apache 2.0 licence), which seems to simplify things. There is also lots of material in Google (as always), but it seems far from conclusive or applicable at times.

 

Haven't properly tested the latter ones, but hope this helps whoever tries serializing/deserializing (well, at least Salesforce SObjects via Axis :-)!

 

Thanks!