JAXB--@XmlElementWrapper注解和泛型一起使用

当java对象的某个属性使用泛型时,普通对象都没问题,但是遇到HashSet这种集合类封装的元素时,就会出现元素内容序列化不出来的问题,详见如下:

 

一、示例:

第一步:定义java对象

 

Java代码  收藏代码
  1. package step3;  
  2.   
  3. import javax.xml.bind.annotation.XmlAccessType;  
  4. import javax.xml.bind.annotation.XmlAccessorType;  
  5. import javax.xml.bind.annotation.XmlRootElement;  
  6.   
  7. @XmlRootElement  
  8. @XmlAccessorType(value = XmlAccessType.PROPERTY)  
  9. public class Customer<T> {  
  10.     String name;  
  11.     int age;  
  12.     int id;  
  13.     T t;  
  14.   
  15.     public String getName() {  
  16.         return name;  
  17.     }  
  18.   
  19.     public void setName(String name) {  
  20.         this.name = name;  
  21.     }  
  22.   
  23.     public int getAge() {  
  24.         return age;  
  25.     }  
  26.   
  27.     public void setAge(int age) {  
  28.         this.age = age;  
  29.     }  
  30.   
  31.     public int getId() {  
  32.         return id;  
  33.     }  
  34.   
  35.     public void setId(int id) {  
  36.         this.id = id;  
  37.     }  
  38.   
  39.       
  40.     @Override  
  41.     public String toString() {  
  42.         return "Customer [id=" + id + ",name=" + name + ",age=" + age + ",t=" + t + "]";  
  43.     }  
  44.   
  45.     public T getT() {  
  46.         return t;  
  47.     }  
  48.   
  49.     public void setT(T t) {  
  50.         this.t = t;  
  51.     }  
  52. }  

 

 

 

Java代码  收藏代码
  1. package step3;  
  2. import javax.xml.bind.annotation.XmlAccessType;  
  3. import javax.xml.bind.annotation.XmlAccessorType;  
  4.   
  5. @XmlAccessorType(value = XmlAccessType.PROPERTY)  
  6. public class Book {  
  7.       
  8.     private String id;  
  9.     private String name;  
  10.     private float price;  
  11.       
  12.     public String getId() {  
  13.         return id;  
  14.     }  
  15.     public void setId(String id) {  
  16.         this.id = id;  
  17.     }  
  18.     public String getName() {  
  19.         return name;  
  20.     }  
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.     public float getPrice() {  
  25.         return price;  
  26.     }  
  27.     public void setPrice(float price) {  
  28.         this.price = price;  
  29.     }  
  30.     @Override  
  31.     public String toString() {  
  32.         return "Book [id=" + id + ",name=" + name + ",price=" + price + "]";  
  33.     }  
  34. }  

 

第二步:编组(JAXBContext.newInstance(Customer.class,HashSet.class);方法添加了

HashSet的class对象,以提供给JAXBContext使用。)

 

Java代码  收藏代码
  1. package step3;  
  2. import java.io.File;  
  3. import java.util.HashSet;  
  4.   
  5. import javax.xml.bind.JAXBContext;  
  6. import javax.xml.bind.JAXBException;  
  7. import javax.xml.bind.Marshaller;  
  8.   
  9. //Marshaller  
  10. public class Object2XmlDemo {  
  11.     public static void main(String[] args) {  
  12.   
  13.         Customer<HashSet<Book>> customer = new Customer<HashSet<Book>>();  
  14.         customer.setId(100);  
  15.         customer.setName("suo");  
  16.         customer.setAge(29);  
  17.           
  18.         Book book = new Book();  
  19.         book.setId("1");  
  20.         book.setName("哈里波特");  
  21.         book.setPrice(100);  
  22.           
  23.         Book book2 = new Book();  
  24.         book2.setId("2");  
  25.         book2.setName("苹果");  
  26.         book2.setPrice(50);  
  27.           
  28.         HashSet<Book> bookSet = new HashSet<Book>();  
  29.         bookSet.add(book);  
  30.         bookSet.add(book2);  
  31.           
  32.         customer.setT(bookSet);  
  33.           
  34.         try {  
  35.             File file = new File("C:\\file1.xml");  
  36.             JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class,  
  37.                     HashSet.class);  
  38.             Marshaller jaxbMarshaller = jaxbContext.createMarshaller();  
  39.             // output pretty printed  
  40.             jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
  41.             jaxbMarshaller.marshal(customer, file);  
  42.             jaxbMarshaller.marshal(customer, System.out);  
  43.         } catch (JAXBException e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47. }  

 

得到的xml:

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2. <customer>  
  3.     <age>29</age>  
  4.     <id>100</id>  
  5.     <name>suo</name>  
  6.     <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="hashSet"/>  
  7. </customer>  

 

 

注:

1.泛型使用集合元素替代时,泛型属性所对应的xml没有序列化出来。

2.若JAXBContext.newInstance(Customer.class,HashSet.class);不添加HashSet

的class对象,则报错:

[javax.xml.bind.JAXBException: class java.util.HashSet nor any of its super class is known to this context.]

 

解决办法:

第一步:新增HashSet的包装类

 

Book类和Customer类相关代码均不需要改变,新增一个HashSet的包装类,定义如下:

 

Java代码  收藏代码
  1. package step4;  
  2.   
  3. import java.util.HashSet;  
  4.   
  5. import javax.xml.bind.annotation.XmlElement;  
  6. import javax.xml.bind.annotation.XmlElementWrapper;  
  7.   
  8. public class BookSet {  
  9.       
  10.     private HashSet<Book> bookSet = new HashSet<Book>();  
  11.   
  12.     //仅包含get方法,未包含set方法  
  13.     @XmlElementWrapper(name = "bookSet")//该注解非必须,仅是标注集合元素  
  14.     @XmlElement(name="book")  
  15.     public HashSet<Book> getBookSet() {  
  16.         return bookSet;  
  17.     }  
  18.   
  19.     public void addBook(Book book){  
  20.         bookSet.add(book);  
  21.     }  
  22.       
  23. }  

 

 

注:

1.BookSet类内部使用HashSet实现.

2.BookSet类在get方法上添加了@XmlElementWrapper(name = "bookSet")注解。

 

第二步:编组

 

Java代码  收藏代码
  1. package step4;  
  2.   
  3. import java.io.File;  
  4.   
  5. import javax.xml.bind.JAXBContext;  
  6. import javax.xml.bind.JAXBException;  
  7. import javax.xml.bind.Marshaller;  
  8.   
  9. //Marshaller  
  10. public class Object2XmlDemo {  
  11.     public static void main(String[] args) {  
  12.   
  13.         Customer<BookSet> customer = new Customer<BookSet>();  
  14.         customer.setId(100);  
  15.         customer.setName("suo");  
  16.         customer.setAge(29);  
  17.           
  18.         Book book = new Book();  
  19.         book.setId("1");  
  20.         book.setName("哈里波特");  
  21.         book.setPrice(100);  
  22.           
  23.         Book book2 = new Book();  
  24.         book2.setId("2");  
  25.         book2.setName("苹果");  
  26.         book2.setPrice(50);  
  27.           
  28.         BookSet bookSet = new BookSet();  
  29.         bookSet.addBook(book);  
  30.         bookSet.addBook(book2);  
  31.           
  32.         customer.setT(bookSet);  
  33.           
  34.         try {  
  35.             File file = new File("C:\\file1.xml");  
  36.             JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class,  
  37.                     BookSet.class);  
  38.             Marshaller jaxbMarshaller = jaxbContext.createMarshaller();  
  39.             // output pretty printed  
  40.             jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
  41.             jaxbMarshaller.marshal(customer, file);  
  42.             jaxbMarshaller.marshal(customer, System.out);  
  43.         } catch (JAXBException e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47. }  

 

 

注:

1.定义Customer对象时,使用包装类,即:

Customer<BookSet> customer = new Customer<BookSet>();

2.JAXBContext调用newInstance()方法时,传入BookSet的class对象,告知BookSet的类型,即:JAXBContext.newInstance(Customer.class,BookSet.class);

 

得到的xml:

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2. <customer>  
  3.     <age>29</age>  
  4.     <id>100</id>  
  5.     <name>suo</name>  
  6.     <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="bookSet">  
  7.         <bookSet>  
  8.             <book>  
  9.                 <id>2</id>  
  10.                 <name>苹果</name>  
  11.                 <price>50.0</price>  
  12.             </book>  
  13.             <book>  
  14.                 <id>1</id>  
  15.                 <name>哈里波特</name>  
  16.                 <price>100.0</price>  
  17.             </book>  
  18.         </bookSet>  
  19.     </t>  
  20. </customer>  

 

posted on 2017-04-22 22:00  ilinux_one  阅读(3599)  评论(0编辑  收藏  举报

导航