Collections of web application techniques

Monday, September 13, 2010

Saving and Retrieving Objects with JAXB

I have done a lot of work using database back end but recently I discovered JAXB. JAXB is not new but for saving a retrieving a Java objects, it is extremely easy and wonderful to use. As demonstrated below, you can accomplish the task of saving the object regardless of how many attributes it might have to a file and read it back in in less than 10 lines of code. For this reason, JAXB perfectly fits my need in creating test cases to test my business logic.

JAXB covers composition and inheritance transparently. The objects to be stored and retrieved may contain other objects or may have inherited attributes.

Here is a simplified Java class. You only need to annotate with the XmlRootElement and the XmlAcessorType tags at the class level.

package com.inventasoft.domain;

import java.util.Date;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
    private Date birthDate;

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
}


Here is the code to create xml content from the object, write it out to a file, and read it back in.


package com.inventasoft.test.jaxb;

import com.inventasoft.domain.Person;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import junit.framework.TestCase;

public class PersonSimpleTest extends TestCase {

    public void testPerson() throws Exception {
        Person testWrite = new Person();

        // write it out as XML
        JAXBContext jaxbContext = JAXBContext.newInstance(testWrite.getClass());
        StringWriter writer = new StringWriter();
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(testWrite, writer);
        writeToFile("test.xml", writer.toString());

        String data = readFromFile("test.xml");

        // read it from XML
        Object o = jaxbContext.createUnmarshaller().unmarshal(
                new StringReader(data));

        Person testRead = (Person) o;

        assertEquals(testWrite.getBirthDate(), testRead.getBirthDate());
    }

    private void writeToFile(String filename, String data)
            throws Exception {
        BufferedWriter bw = null;
        try {
            File f = new File(filename);
            bw = new BufferedWriter(new FileWriter(f));
            bw.write(data);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null)
                bw.close();
        }
    }

    private String readFromFile(String filename) throws Exception {
        BufferedReader br = null;
        StringBuilder content = new StringBuilder();
        try {
            File f = new File(filename);
            br = new BufferedReader(new FileReader(f));
            String line = null;
            while ((line = br.readLine()) != null) {
                content.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null)
                br.close();
        }
        return content.toString();
    }
}


And here is the sample ouput XML:



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Person>
    <birthDate>2010-09-13T08:52:25.298-06:00</birthDate>
</Person>


The JAXB files you will need are jaxb-impl.jar, jaxb-xjc.jar.

2 comments: