I was looking for a quick and simple way of passing a Java object between two Java programs with a wire connection between.
My first thought was object serialization. The problem with this mechanism is that it’s very brittle (change an object on one side and not the other and it goes bang!!). Also, it only really works if you have control of the JVM levels on either side. Which in this case I did, but if I was to share the code with others then they might not be in the same position.
I next considered what XML utilities were packed with the latest JVMs. This led me to JAXB. It seemed an ideal solution. Though it did imply that I either had to start from some XSD, or I had to correctly annotate the classes that I wanted to encode. This seemed a bit more overhead than what I was after.
Obviously there are other solutions… Web Services, 3rd party XML / JSON tools. But again, the consideration around overhead and also the hassle of downloading 3rd party libraries turned me away. After all, I’m just after a quick and simple solution for what is a basic application.
In sMash I would have used some of the great JSON / XML libraries that are supplied out of the box. But I’m not using sMash this time, so I need to look at what’s supplied in the Java class library.
After chatting with a colleague I found the answer.
He recommended I use the java.beans.XMLEncoder & java.beans.XMLDecoder classes. After a bit of fiddling with Input/Output streams I created some utility methods that allow me to make a single call to these services. They encode / decode any Java object that follows the Java Beans specification i.e. it has a zero arguments constructor and getter / setter methods for all variables in the class.
I have pasted the utility methods here for your convenience. Note, because I am running this code on the mainframe I need to explictly request that the bytes be returned in UTF-8 format.
public static String getXMLFromObject(Object object)
{
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final XMLEncoder encoder = new XMLEncoder(outputStream);
String result = null;
encoder.writeObject(object);
encoder.close();
try { result = new String(outputStream.toByteArray(), "UTF-8"); }
catch (UnsupportedEncodingException e) { e.printStackTrace(); }
return result;
}
public static Object getObjectFromXML(String xml)
{
Object result = null;
try
{
final ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.trim().getBytes("UTF-8"));
XMLDecoder decoder = new XMLDecoder(inputStream);
result = decoder.readObject();
decoder.close();
}
catch (UnsupportedEncodingException e) { e.printStackTrace(); }
return result;
}
(apologies for the dodgy formatting. It comes out ok on the editor screen)