sabato 23 maggio 2015

Grails and Groovy xml marshalling and unmarshalling

Grails and Groovy xml marshalling and unmarshalling

Converting JSON to a map object is a very simple task to perform in Groovy. But what if you need to marshal and unmarshal xml?
I will show a simple way on how to do it.
Suppose we have a reservation xml we want to marshal:

<ns2:roomReservation xmlns:ns2="http://an.address.com/">
    <customerId locale="en_US">F3F0C7</customer>
    <itineraryId>205216012</itineraryId>
    <rooms>
      <room>301</room>
      <room>302</room>
    </rooms>
    <info>
      <start>2015-05-23</start>
      <end>2015-05-26</end>
    </info>
</ns2:roomReservation>

Ok now we must define classes to marshal xml to. Let's define a RoomReservation groovy class which must implements Serializable

package com.test.a
import javax.xml.bind.annotation.*

@XmlRootElement(name="roomReservation", namespace="http://an.address.com/")
@XmlAccessorType(XmlAccessType.FIELD)
class RoomReservation implements Serializable {

@XmlElement String customerId
@XmlAttribute String locale
@XmlElement long itineraryId
@XmlElement(name="rooms") List<Room> roomList
@XmlElement(name="info") Info info
}

Let's have a look at this class: this class bind roomReservation tag to this class and maps all the fields within.
Any attribute is mapped by @XmlAttribute annotation and the rooms tag is mapped as a List (roomList groovy property).
Pay attention!!! Any time you define a non simple Object or type property, you must use (name="xmltag") to map it to your specific class such as for Info class and List.

Now let's have a look at our Info class:

package com.test.a
import javax.xml.bind.annotation.*

@XmlRootElement(name="info")
@XmlAccessorType(XmlAccessType.FIELD)
class Info implements Serializable {

@XmlElement String start
@XmlElement String end
}

Now that we have mapped our structures, we can unmarshal xml this way:

String xml
...
... //we omit how to get xml but it will be stored in xml variable
def jaxbContext= JAXBContext.newInstance(RoomReservation.class)
def unmarshaller = jaxbContext.createUnmarshaller()
RoomReservation roomReservation = unmarshaller.unmarshal(new StringReader(xml))

or marshal this way (using the RoomReservation already defined and populated):

def jaxbContext = JAXBContext.newInstance(RoomReservation.class)
def marshaller = jaxbContext.createMarshaller()
StringWriter writer = new StringWriter();
marshaller.marshal(roomReservation, writer)
String xml = writer.toString()

So this is a very simple way to marshal and unmarshal xml to Groovy objects.

Now that you have read my article, i would like to show you another thing: i've developed an app to help increase customers registration and customers conversion.

You can find it at appromocodes.com