JAXB the life saver

My most recent assignment is to integrate all of the client’s pricing service and deliver a price comparison service. When I generating the service stub from the WSDL provided (Yeap, it’s SOAP). It generate a strange little interface method which look like this:

public String doStuff(String input);

This is weird, why it expected a string, I thought they require more input than a simple string. I tried to generate the stub again, of course, nothing changed.

So, after communicating with their IT team, turn out, they do expected a string, a freaking xml string, with reason of they don’t have to worry on change in WSDL in future when extra input is required. So, I seek advice from my superior.

Hmm, quite brilliant, we don’t have to generate other client if there’s any changes on their service.

I can’t believe that’s his comment. Anyway, I am not going to hand craft xml. Since I can’t convince anyone that this design isn’t a good idea. Still, I am lucky to convince my boss to upgrade the JDK to version 1.6 (you read that right, we were using version 1.5 and it’s 2017)

Java Architect XML Binding come with JDK 1.6, it simplify the XML POJO conversion. With simple annotation I could serialize a POJO to XML string and vice versa.

@XmlRootElement(name="input")
public class SomeInputXml{
    private String id;
    private String name;

    @XmlElement(name="uuid")
    public String getId(){
        return id;
    }

    @XmlElement(name="name")
    public String getName(){
        return name;
    }
}

With about POJO with some jaxb annotation, I can form a xml look like so,

<input>
    <uuid>somevalue</uuid>
    <name>somename</name>
</input>

There’s more JAXB can do like adding attribute and ignore some property. And the process of marshaling POJO to XML is extremely simple as well.

//This object will hold all of the pojo's xml metadata.
//It is resource heavy to create
//meant to be create once and reuse everywhere
JAXBContext context = JAXBContext.newInstance(SomeInputXml.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(someObject,baos);
baos.toString();//with this step, I could easily form a xml String

JAXB is quite useful when some work on xml generation or reading is required. I used it to read some sort of xml configuration file handcrafted by my colleague and reuse the POJO since DOM API’s Document is not thread safe to share along.

A good place to instantiate a JAXBContext will be in a either Singleton or ApplicationScope producer bean.

@ApplicationScoped
public class SomeConfig{
    private JAXBContext context;
    @PostConstruct
    public void init(){
         //initialization
    }
     
    @Produces //Or you could give a Marshaller 
    public JAXBContext getContext(){
       return context;
    }

}

One thing to note that CDI ApplicationScoped is lazy, it will be instantiate once when the first call is invoke (in this case it will trigger by Injecting JAXBContext)

One could make it eager init by replacing it by EJB’s singleton and Startup together.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s