1

I have a simpe XML that I want to unmarshall into a model class. I have annotated the class with JAXB annotations for defining the access type (FIELD):

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

@XmlAccessorType(XmlAccessType.FIELD)
public class DtoTest {

    private String name;

    public DtoTest() {}

    public DtoTest(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "DtoTest [name=" + name + "]";
    }
}

This is my main class where I run an unmarshal method against a simple XML saved in a String variable:

public class Test {

    public static void main(String[] args) throws Exception {
        Object obj = new DtoTest();
        String testXML = "<dtoTest><name>example</name></dtoTest>";
        obj = unmarshal(obj, testXML);
        System.out.println(obj);
    }

    /* This is a generic unmarshall method which I've already used with success with other XML*/
    public static <T> T unmarshal(T obj, String xml) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));

        Class<? extends Object> type = obj.getClass();
        JAXBContext jc = JAXBContext.newInstance(type);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        obj =  (T)unmarshaller.unmarshal(xsr, type).getValue();
        xsr.close();

        return obj;
    }
}

Whenever I run the code I get the same output:

DtoTest [name=null]

I don't understand what I'm doing wrong.

Baderous
  • 1,069
  • 1
  • 11
  • 32
  • I tried your example in my simple project, and works fine. :) can you add the version of all your libraries? (output is DtoTest [name=example]) i used only difference `XMLInputFactory xif = XMLInputFactory.newInstance();` – Xstian Oct 29 '14 at 16:36
  • I'm running this code in a simple java project that uses JavaSE 1.7, I don't have any extra jar or dependecy configured. – Baderous Oct 29 '14 at 16:41
  • I found that there was a package-info class in the same package that was responsible for the strange behavior. After I removed it, everything worked fine. – Baderous Oct 30 '14 at 09:20

2 Answers2

2

I've just run your code on jdk1.7.0_67 and it works.

DtoTest [name=example]

Maybe you have some problem with included libraries? I've run it with just plain java.

Marek Smigielski
  • 341
  • 1
  • 2
  • 9
1

What you have in your question runs perfectly fine for me. One optimization you could make to it is to create an StreamSource instead of an XMLStreamReader.

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;

public class Test {

    public static void main(String[] args) throws Exception {
        Object obj = new DtoTest();
        String testXML = "<dtoTest><name>example</name></dtoTest>";
        obj = unmarshal(obj, testXML);
        System.out.println(obj);
    }

    public static <T> T unmarshal(T obj, String xml) throws Exception {
        StreamSource source = new StreamSource(new StringReader(xml));

        Class<? extends Object> type = obj.getClass();
        JAXBContext jc = JAXBContext.newInstance(type);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        obj =  (T)unmarshaller.unmarshal(source, type).getValue();

        return obj;
    }

}

Debugging Tip

When unmarshalling is not working as expected, populate your JAXB model and marshal it to XML to see what the expected XML looks like.

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • I found that there was a package-info class in the same package that was responsible for the strange behavior. After I removed it, everything worked fine. Thanks for the optimization tip. – Baderous Oct 30 '14 at 09:21