Using JAXB to unmarshal/marshal a List<String>

jaxb unmarshal list of objects
jaxb unmarshal list of strings
xml marshalling and unmarshalling in java using jaxb
jaxb list of elements without wrapper
how to unmarshal complex xml using jaxb
unmarshal soap message (xml) to java object using jaxb
jaxb unmarshal xml with multiple objects
jaxb multiple root elements

I'm trying to create a very simple REST server. I just have a test method that will return a List of Strings. Here's the code:


@GET
@Path("/test2")
public List test2(){
    List list=new Vector();
    list.add("a");
    list.add("b");
    return list;
}

It gives the following error:

SEVERE: A message body writer for Java type,
class java.util.Vector, and MIME media type,
application/octet-stream, was not found

I was hoping JAXB had a default setting for simple types like String, Integer, etc. I guess not. Here's what I imagined:

<Strings>
  <String>a</String>
  <String>b</String>
</Strings>

What's the easiest way to make this method work?

I used @LiorH's example and expanded it to:


@XmlRootElement(name="List")
public class JaxbList<T>{
    protected List<T> list;

    public JaxbList(){}

    public JaxbList(List<T> list){
        this.list=list;
    }

    @XmlElement(name="Item")
    public List<T> getList(){
        return list;
    }
}

Note, that it uses generics so you can use it with other classes than String. Now, the application code is simply:


    @GET
    @Path("/test2")
    public JaxbList test2(){
        List list=new Vector();
        list.add("a");
        list.add("b");
        return new JaxbList(list);
    }

Why doesn't this simple class exist in the JAXB package? Anyone see anything like it elsewhere?

Using JAXB for XML With Java, . In this XmlToProductTest class, a JAXBContext initialized with Product is used. The createUnmarsheller() method returns an Unmarshaller. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. JAXB mostly is used while implementing webservices or any other such client interface […]

@GET
@Path("/test2")
public Response test2(){
   List<String> list=new Vector<String>();
   list.add("a");
   list.add("b");

   final GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) { };
   return Response.ok().entity(entity).build();
}

JAXB hello world example – Mkyong.com, – Convert a Java object into a XML file. Unmarshalling – Convert XML content into a Java Object. JAXB: MARSHALLING AND UNMARSHALLING LIST OF OBJECTS. //Converting XML to java object using JAXB unmarshal API. subscribers = (Subscribers)

In case anyone of you wants to write a list wrapper for lists containing elements of multiple classes and want to give an individual XmlElement name according to the Class type without Writing X Wrapper classes you could use the @XmlMixed annotation. By doing so JAXB names the items of the list according to the value set by the @XmlRootElement. When doing so you have to specify which classes could possibly be in the list using @XmlSeeAlso

Example:

Possible Classes in the list

@XmlRootElement(name="user")
public class User {/*...*/}

@XmlRootElement(name="entry")
public class LogEntry {/*...*/}

Wrapper class

@XmlRootElement(name="records")
@XmlSeeAlso({User.class, LogEntry.class})
public static class JaxbList<T>{

    protected List<T> records;

    public JaxbList(){}

    public JaxbList(List<T> list){
        this.records=list;
    }

    @XmlMixed 
    public List<T> getRecords(){
        return records;
    }
}

Example:

List l = new List();
l.add(new User("userA"));
l.add(new LogEntry(new UserB()));


XStream xStream = new XStream();
String result = xStream.toXML(l);

Result:

<records>
    <user>...</user>
    <entry>...</entry>
</records>

Alternatevily you could specify the XmlElement names directly inside the wrapper class using the @XmlElementRef annotation

@XmlRootElement(name="records")
@XmlSeeAlso({User.class, LogEntry.class})
public static class JaxbList<T>{

    protected List<T> records;

    public JaxbList(){}

    public JaxbList(List<T> list){
        this.records=list;
    }

    @XmlElementRefs({
        @XmlElementRef(name="item", type=Object.class),
        @XmlElementRef(name="user", type=User.class),
        @XmlElementRef(name="entry", type=LogEntry.class)
    })
    public List<T> getRecords(){
        return records;
    }
}

JAXB Tutorial: How to Marshal and Unmarshal XML, a source/reader and the expected root object. // Unmarshallers are not thread-safe. Create a new one every time. In this JAXB example we will see how to marshall and unmarshall list of objects. Environment Used: JDK 6. Eclipse Indigo IDE for Java EE Developers. New project in Eclipse. Create a new Java project in Eclipse IDE and name it as “JAXBList“. Create Bean class

From a personal blog post, it is not necessary to create a specific JaxbList < T > object.

Assuming an object with a list of strings:

@XmlRootElement
public class ObjectWithList {

    private List<String> list;

    @XmlElementWrapper(name="MyList")
    @XmlElement
    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

}

A JAXB round trip:

public static void simpleExample() throws JAXBException {

    List<String> l = new ArrayList<String>();
    l.add("Somewhere");
    l.add("This and that");
    l.add("Something");

    // Object with list
    ObjectWithList owl = new ObjectWithList();
    owl.setList(l);

    JAXBContext jc = JAXBContext.newInstance(ObjectWithList.class);
    ObjectWithList retr = marshallUnmarshall(owl, jc);

    for (String s : retr.getList()) {
        System.out.println(s);
    } System.out.println(" ");

}

Produces the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<objectWithList>
    <MyList>
        <list>Somewhere</list>
        <list>This and that</list>
        <list>Something</list>
    </MyList>
</objectWithList>

Consuming Web Services: Marshalling with JAXB, is the opposite. The flattening of an object to an XML String. This JAXB tutorial describes how to use JAXB to marshal and unmarshal XML strings using either Spring or the standard javax.xml.bind interfaces. The samples below are using XML strings instead of files, but could easily be adapted to files if needed. Spring’s Jaxb2Marshaller Configuration

This can be done MUCH easier using wonderful XStream library. No wrappers, no annotations.

Target XML
<Strings>
  <String>a</String>
  <String>b</String>
</Strings>
Serialization

(String alias can be avoided by using lowercase string tag, but I used OP's code)

List <String> list = new ArrayList <String>();
list.add("a");
list.add("b");

XStream xStream = new XStream();
xStream.alias("Strings", List.class);
xStream.alias("String", String.class);
String result = xStream.toXML(list);
Deserialization

Deserialization into ArrayList

XStream xStream = new XStream();
xStream.alias("Strings", ArrayList.class);
xStream.alias("String", String.class);
xStream.addImplicitArray(ArrayList.class, "elementData");
List <String> result = (List <String>)xStream.fromXML(file);

Deserialization into String[]

XStream xStream = new XStream();
xStream.alias("Strings", String[].class);
xStream.alias("String", String.class);
String[] result = (String[])xStream.fromXML(file);

Note, that XStream instance is thread-safe and can be pre-configured, shrinking code amount to one-liners.

XStream can also be used as a default serialization mechanism for JAX-RS service. Example of plugging XStream in Jersey can be found here

Using JAXB to unmarshal/marshal a List<String>, I used @LiorH's example and expanded it to: @XmlRootElement(name="List") public class JaxbList<T>{ protected List<T> list; public JaxbList(){} public  JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. JAXB mostly is used while implementing webservices or any other such client interface for an application where data needs to be transferred in XML format instead of HTML format which is default in case of visual client like web browsers.

JAXB: Marshalling and Unmarshalling list of objects – iByteCode , java” in the package “com.theopentutorials.jaxb.to” to hold the list of Book objects by having an ArrayList instance variable in our class. This class is a simple holder of list of book objects. We will use this class to marshal and unmarshal list of objects. The createUnmarsheller() method returns an Unmarshaller. A JAXB Unmarshaller governs the process of unmarhshalling XML data into a Java object tree. Finally, the unmarshal() method unmarshals the File object for product.xml into the Product POJO. The output on running the test is this.

JAXB: Marshall and Unmarshalling list of objects, In this tutorial we will see how to Marshall and Unmarshall list of objec. Converting java object to xml using JAXB marshal API. Java Architecture for XML Binding (JAXB) is a library that helps bind XML schemas and Java representations. JAXB provides you with a mechanism to marshal Java objects into XML and the other way around – unmarshal XML into Java objects. XML is an industry standard for defining the contents of your message.

Marshalling and Unmarshalling in JAXB 2.0, how to use JAXB to marshal and unmarshal XML strings using either List of java packages that contain the jaxb generated classes -->. The JAXB Unmarshaller interface is responsible for governing the process of deserializing the XML data to Java Objects. The unmarshalling to objects can be done to variety of input sources. Generally, to create Unmarshaller you can reuse this code. String xmlString = ""; There currently are not any properties required to be supported by all

Comments
  • Similar: JAXB: How to marshal objects in lists?
  • trying to unmarshall this with a cxf proxy led to java.lang.NullPointerException at com.sun.xml.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:305)
  • This did not work for me as well. I got an error: No writer for JaxbList. Finally I've solved it using JacksonJaxbJsonProvider. No Java code needs to be modified. Just few changes in Spring context.xml and Maven pom.xml, see stackoverflow.com/a/30777172/1245231
  • Still useful 2 years later :)
  • Still useful 3 years later :)
  • This does not work for me. Using Jersey 1.11 w/Glasfish 3.1.2. I get javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.Vector, and Java type java.util.List<java.lang.String>, and MIME media type application/json was not found
  • Can you please tell if there is an ability to use names as alias for classes by default? I have a very complex class, it contains lots of classes objects that contain classes objects that contain classes objects and so on... Is there any way to avoid thousends of calling xStream.alias(...)? Thanks
  • Actually, you may serialize your class without any aliases at all, or with just alias to a root class. It will name the root tag as you've aliased (or use fully qualified class name if you didn't) and name all inner tags the same way inner fields of classes are named. Enjoy!
  • The point is that the full name of class (including package) is unwanted for me. I want just name and not to define aliases for all used classes, because it will take a lot of space and time. Can you advice me something?
  • As I said, alias only the root class and check XStream generated XML.
  • looks like a great start. But this doesn't look thread safe.
  • you can remove the static modifier from the inner class if same instance of the top class can serve more than one thread.
  • I'm probably doing something wrong. I'm not sure how to use the Response object you mentioned. So, I just used the code above and got: javax.ws.rs.WebApplicationException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions XmlElementRef points to a non-existent class. Any ideas?
  • you are right, my mistake, trying to write code without running it. i fixed it.
  • The inner class must be static, or the following error will occur: ResourceWrapper is a non-static inner class, and JAXB can't handle those.