Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I marshall multiple objects using JAXB?

I'm trying to marshall multiple objects e.g. Book added into BookLists via setBookslst(). I begin using this JAXBContext setup:

jaxbContext = JAXBContext.newInstance(BookLists.class);

and

 jaxbMarshaller.marshal(lists, result);

I'm given the following runtime exception however:

javax.xml.bind.JAXBException: com.jaxb.example.marshall.Book nor any of its super class is known to this context]

My types are defined as follows.

Book :-

@XmlRootElement(name="book")
public class Book {

     private String title;
     private int year;
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
}

BookList :-

@XmlRootElement(name="lists")
public class BookLists {
List<Book> bookslst;

public List getBookslst() {
    return bookslst;
}

public void setBookslst(List bookslst) {
    this.bookslst = bookslst;
}

}

Marshall Code:-

Book book;
    BookLists lists=new BookLists();
    List lst=new ArrayList();
    book = new Book();
    book.setTitle("Book title");
    book.setYear(2010);
    lst.add(book);
    book = new Book();
    book.setTitle("Book title1");
    book.setYear(2011);
    lst.add(book);
    lists.setBookslst(lst);
    JAXBContext jaxbContext;
    try {
        jaxbContext = JAXBContext.newInstance(BookLists.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter result = new StringWriter();

        jaxbMarshaller.marshal(lists, result);
        String xml = result.toString();
        System.out.println(xml);
    } catch (JAXBException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

I am trying to put @XMLSeeAlso annotations(Ref:- JAXB Exception: Class not known to this context). This annotation is not available in my version.

like image 989
user1357722 Avatar asked Sep 07 '12 18:09

user1357722


People also ask

How does JAXB marshalling work?

In JAXB, marshalling involves parsing an XML content object tree and writing out an XML document that is an accurate representation of the original XML document, and is valid with respect the source schema. JAXB can marshal XML data to XML documents, SAX content handlers, and DOM nodes.


1 Answers

By default a JAXB (JSR-222) implementation examines the public accessor methods. You could add the Book parameter on the List in your get/set methods.

public List<Book> getBookslst() {
    return bookslst;
}

public void setBookslst(List<Book> bookslst) {
    this.bookslst = bookslst;
}

Alternatively you could specify the type of the property using the @XmlElement annotation:

@XmlElement(type=Book.class)
public List getBookslst() {
    return bookslst;
}

You could also specify that your JAXB implementation introspect the fields instead of the properties:

@XmlRootElement(name="lists")
@XmlAccessorType(XmlAccessType.FIELD)
public class BookLists {
    List<Book> bookslst;
}

UPDATE

Is there any alternative way to add List instead of BookList in Marshallar.Marshall?

You could create a generic List wrapper object that leveraged the @XmlAnyElement(lax=true) annotation (see: http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html). Then it cold handle a List of anything annotated with @XmlRootElement.

Lists

package forum12323397;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Lists<VALUE> {

    private List<VALUE> values = new ArrayList<VALUE>();

    @XmlAnyElement(lax=true)
    public List<VALUE> getValues() {
        return values;
    }

}

Demo

package forum12323397;

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Lists.class, Book.class);

        Lists<Book> lists = new Lists<Book>();

        Book book1 = new Book();
        book1.setTitle("A Book");
        book1.setYear(2001);
        lists.getValues().add(book1);

        Book book2 = new Book();
        book2.setTitle("Another Book");
        book2.setYear(2007);
        lists.getValues().add(book2);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(lists, System.out);
    }

}

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<lists>
    <book>
        <title>A Book</title>
        <year>2001</year>
    </book>
    <book>
        <title>Another Book</title>
        <year>2007</year>
    </book>
</lists>
like image 179
bdoughan Avatar answered Oct 23 '22 05:10

bdoughan