`
wode66
  • 浏览: 737596 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多

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

 

一、示例:

第一步:定义java对象

 

package step3;

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

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.PROPERTY)
public class Customer<T> {
	String name;
	int age;
	int id;
	T t;

	public 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;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	
	@Override
	public String toString() {
		return "Customer [id=" + id + ",name=" + name + ",age=" + age + ",t=" + t + "]";
	}

	public T getT() {
		return t;
	}

	public void setT(T t) {
		this.t = t;
	}
}

 

 

 

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

@XmlAccessorType(value = XmlAccessType.PROPERTY)
public class Book {
	
	private String id;
	private String name;
	private float price;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ",name=" + name + ",price=" + price + "]";
	}
}
 

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

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

 

package step3;
import java.io.File;
import java.util.HashSet;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

//Marshaller
public class Object2XmlDemo {
	public static void main(String[] args) {

		Customer<HashSet<Book>> customer = new Customer<HashSet<Book>>();
		customer.setId(100);
		customer.setName("suo");
		customer.setAge(29);
		
		Book book = new Book();
		book.setId("1");
		book.setName("哈里波特");
		book.setPrice(100);
		
		Book book2 = new Book();
		book2.setId("2");
		book2.setName("苹果");
		book2.setPrice(50);
		
		HashSet<Book> bookSet = new HashSet<Book>();
		bookSet.add(book);
		bookSet.add(book2);
		
		customer.setT(bookSet);
		
		try {
			File file = new File("C:\\file1.xml");
			JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class,
					HashSet.class);
			Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
			// output pretty printed
			jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			jaxbMarshaller.marshal(customer, file);
			jaxbMarshaller.marshal(customer, System.out);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}
}

 

得到的xml:

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
    <age>29</age>
    <id>100</id>
    <name>suo</name>
    <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="hashSet"/>
</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的包装类,定义如下:

 

package step4;

import java.util.HashSet;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

public class BookSet {
	
	private HashSet<Book> bookSet = new HashSet<Book>();

	//仅包含get方法,未包含set方法
	@XmlElementWrapper(name = "bookSet")//该注解非必须,仅是标注集合元素
	@XmlElement(name="book")
	public HashSet<Book> getBookSet() {
		return bookSet;
	}

	public void addBook(Book book){
		bookSet.add(book);
	}
	
}

 

 

注:

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

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

 

第二步:编组

 

package step4;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

//Marshaller
public class Object2XmlDemo {
	public static void main(String[] args) {

		Customer<BookSet> customer = new Customer<BookSet>();
		customer.setId(100);
		customer.setName("suo");
		customer.setAge(29);
		
		Book book = new Book();
		book.setId("1");
		book.setName("哈里波特");
		book.setPrice(100);
		
		Book book2 = new Book();
		book2.setId("2");
		book2.setName("苹果");
		book2.setPrice(50);
		
		BookSet bookSet = new BookSet();
		bookSet.addBook(book);
		bookSet.addBook(book2);
		
		customer.setT(bookSet);
		
		try {
			File file = new File("C:\\file1.xml");
			JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class,
					BookSet.class);
			Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
			// output pretty printed
			jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			jaxbMarshaller.marshal(customer, file);
			jaxbMarshaller.marshal(customer, System.out);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}
}

 

 

注:

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

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

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

 

得到的xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
    <age>29</age>
    <id>100</id>
    <name>suo</name>
    <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="bookSet">
        <bookSet>
            <book>
                <id>2</id>
                <name>苹果</name>
                <price>50.0</price>
            </book>
            <book>
                <id>1</id>
                <name>哈里波特</name>
                <price>100.0</price>
            </book>
        </bookSet>
    </t>
</customer>
 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics