JAXB的应用之二---------Xml与多个对象的映射(聚合或组合)及注意事项

来源:互联网 发布:java 图片高斯模糊 编辑:程序博客网 时间:2024/05/11 16:45

   在我们的实际应用中,Xml中的结构往往不止这么简单,一般都会有2,3层。也就是说如果映射成对象就是聚合(组合)的情况 。

就用我们上一章的例子继续来讲,简单我们的Book的author现在不止是一个String类型的名子,他是一个对象Author,并包含作者的相关个人信息。那我们怎么做列?

直接看代码

package com.jaxb.first;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.XmlType;@XmlRootElement(name = "book")// If you want you can define the order in which the fields are written// Optional@XmlType(propOrder = { "name", "author", "publisher", "isbn" })public class Book {private String name;private Author author;private String publisher;private String isbn;// If you like the variable name, e.g. "name", you can easily change this// name for your XML-Output:public String getName() {return name;}public void setName(String name) {this.name = name;}public Author getAuthor() {return author;}public void setAuthor(Author author) {this.author = author;}public String getPublisher() {return publisher;}public void setPublisher(String publisher) {this.publisher = publisher;}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}}

package com.jaxb.first;import javax.xml.bind.annotation.XmlAttribute;public class Author {private String name;private int age;@XmlAttributepublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}


package com.jaxb.first;import java.util.ArrayList;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlElementWrapper;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(namespace="abc")public class Bookstore {// XmLElementWrapper generates a wrapper element around XML representation@XmlElementWrapper(name = "bookList")// XmlElement sets the name of the entities@XmlElement(name = "book")private ArrayList<Book> bookList;private String name;private String location;public void setBookList(ArrayList<Book> bookList) {this.bookList = bookList;}public ArrayList<Book> getBooksList() {return bookList;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}}
 


package com.jaxb.first;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.Writer;import java.util.ArrayList;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;import com.sun.xml.bind.marshaller.NamespacePrefixMapper;public class BookMain {private static final String BOOKSTORE_XML = "./bookstore-jaxb.xml";public static void main(String[] args) throws JAXBException, IOException {ArrayList<Book> bookList = new ArrayList<Book>();// create booksBook book1 = new Book();book1.setIsbn("978-0060554736");book1.setName("The Game");Author a = new Author();a.setAge(28);a.setName("Gosling");book1.setAuthor(a);book1.setPublisher("Harpercollins");bookList.add(book1);Book book2 = new Book();book2.setIsbn("978-3832180577");book2.setName("Feuchtgebiete");Author a2 = new Author();a2.setAge(32);a2.setName("James Green");book2.setAuthor(a2);book2.setPublisher("Dumont Buchverlag");bookList.add(book2);// create bookstore, assigning bookBookstore bookstore = new Bookstore();bookstore.setName("Fraport Bookstore");bookstore.setLocation("Frankfurt Airport");bookstore.setBookList(bookList);// create JAXB context and instantiate marshallerJAXBContext context = JAXBContext.newInstance(Bookstore.class);Marshaller m = context.createMarshaller();NamespacePrefixMapper mapper = new PreferredMapper();m.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);m.marshal(bookstore, System.out);Writer w = null;try {w = new FileWriter(BOOKSTORE_XML);m.marshal(bookstore, w);} finally {try {w.close();} catch (Exception e) {}}// get variables from our xml file, created beforeSystem.out.println();System.out.println("Output from our XML File: ");Unmarshaller um = context.createUnmarshaller();Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader(BOOKSTORE_XML));for (int i = 0; i < bookstore2.getBooksList().toArray().length; i++) {System.out.println("Book " + (i + 1) + ": "+ bookstore2.getBooksList().get(i).getName() + " from "+ bookstore2.getBooksList().get(i).getAuthor());}}public static class PreferredMapper extends NamespacePrefixMapper {@Overridepublic String getPreferredPrefix(String namespaceUri,String suggestion, boolean requirePrefix) {return "pre";}}}


看下输出结果:

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><pre:bookstore xmlns:pre="abc">    <bookList>        <book>            <name>The Game</name>            <author name="Gosling">                <age>28</age>            </author>            <publisher>Harpercollins</publisher>            <isbn>978-0060554736</isbn>        </book>        <book>            <name>Feuchtgebiete</name>            <author name="James Green">                <age>32</age>            </author>            <publisher>Dumont Buchverlag</publisher>            <isbn>978-3832180577</isbn>        </book>    </bookList>    <location>Frankfurt Airport</location>    <name>Fraport Bookstore</name></pre:bookstore>Output from our XML File: Book 1: The Game from com.jaxb.first.Author@1774b9bBook 2: Feuchtgebiete from com.jaxb.first.Author@104c575


OK 是我们想要的格式吧。 那么事情就解决了

   值 得注意的是:如果你要对属性做注解,必须将注解写在属性的get方法上, 就如我们Author类中的 @XmlAttribute那样,否则运行的时候他会提示:the same element name xxx..