其实XStream和JAXB在一些观念上是很相似的,但是JAXB作为Java EE的一个规范,是非常正式的,且和其他很多规范有联系 是一种标准的实现。
区别:
jaxb2如果没有加@XmlElement等注释,是不会写入到xml中的,但是XStream不会
XStream没有加上注释,默认以属性名称写入子级的元素中
XStream还可以将bean转为json,功能比较强悍,个人建议使用XStream
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。
JDK中JAXB相关的重要Class和Interface:
JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。
Marshaller接口,将Java对象序列化为XML数据。
Unmarshaller接口,将XML数据反序列化为Java对象。
JDK中JAXB相关的重要Annotation:(来源于百度百科JAXB)
@XmlType,将Java类或枚举类型映射到XML模式类型
@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE。
@XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序。
@XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。
@XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)。
@XmlRootElement,将Java类或枚举类型映射到XML元素。
@XmlElement,将Java类的一个属性映射到与属性同名的一个XML元素。
@XmlAttribute,将Java类的一个属性映射到与属性同名的一个XML属性。
在以上的注解中,用的最多的是@XMLType,@XmlAccessorType,@XmlRootElement。
实现步骤:
1.一个实体类,使用@XmlRootElement表示一下类(最简单的)
2.建立一个ObjectFactory用来产生这个实体类
3.使用JAXBContext 然后产生Marshaller(对象-->xml)或者UnMarshaller(xml-->对象)
示例代码:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
public class JAXB2Tester {
public static void main(String[] args) throws JAXBException,IOException {
JAXBContext context = JAXBContext.newInstance(Person.class);
//下面代码演示将对象转变为xml
Marshaller m = context.createMarshaller();
Address address = new Address("China","Beijing","Beijing","ShangDi West","100080");
Person p = new Person(Calendar.getInstance(),"JAXB2",address,Gender.MALE,"SW");
FileWriter fw = new FileWriter("person.xml");
m.marshal(p,fw);
//下面代码演示将上面生成的xml转换为对象
FileReader fr = new FileReader("person.xml");
Unmarshaller um = context.createUnmarshaller();
Person p2 = (Person)um.unmarshal(fr);
System.out.println("Country:"+p2.getAddress().getCountry());
}
}
@XmlRootElement//表示person是一个根元素
class Person {
@XmlElement
Calendar birthDay; //birthday将作为person的子元素
@XmlAttribute
String name; //name将作为person的的一个属性
public Address getAddress() {
return address;
}
@XmlElement
Address address; //address将作为person的子元素
@XmlElement
Gender gender; //gender将作为person的子元素
@XmlElement
String job; //job将作为person的子元素
public Person(){
}
public Person(Calendar birthDay, String name, Address address, Gender gender, String job) {
this.birthDay = birthDay;
this.name = name;
this.address = address;
this.gender = gender;
this.job = job;
}
}
enum Gender{
MALE(true),
FEMALE (false);
private boolean value;
Gender(boolean _value){
value = _value;
}
}
class Address {
@XmlAttribute
String country;
@XmlElement
String state;
@XmlElement
String city;
@XmlElement
String street;
String zipcode; //由于没有添加@XmlElement,所以该元素不会出现在输出的xml中
public Address() {
}
public Address(String country, String state, String city, String street, String zipcode) {
this.country = country;
this.state = state;
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
public String getCountry() {
return country;
}
}
运行该程序,我们会得到一个person.xml的文件,如下:
2006-12-28T08:49:27.203+00:00
Beijing
Beijing
ShangDi West
MALE
SW
控制台会输出
Country:China
1.首先从XStream官网下载XStream
http://xstream.codehaus.org/download.html
2.下载后解压 将lib下的jar添加入项目就可以了
然后就可以编写代码了,为了方便直接使用XStream的annotation:
3.实体类 Person:
package org.cc.vo;
import java.util.List;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@XStreamAlias("Person")
public class Person {
@XStreamAlias("name")
@XStreamAsAttribute
private String name;
@XStreamAlias("age")
private int age;
@XStreamAlias("sex")
private boolean sex;
@XStreamImplicit(itemFieldName="favor")
private List favor;
@XStreamOmitField
private int tempid;
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 boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public List getFavor() {
return favor;
}
public void setFavor(List favor) {
this.favor = favor;
}
public int getTempid() {
return tempid;
}
public void setTempid(int tempid) {
this.tempid = tempid;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex
+ ", favor=" + favor + ", tempid=" + tempid + "]";
}
}
@XStreamAlias(value)是别名 可以用在类名和属性名上修改显示的xml中的标签
@XStreamAsAttribute 把属性作为xml中的属性 而不是子元素
@XStreamImplicit(itemFieldName="favor") 还有一个keyFieldName的属性 这个是用来改写List和Map的显示 的
@XStreamOmitField 此标记的属性不会序列化
4.接下去只有一步,没有JAXB的建立ObjectFactory那一部,实现起来非常简洁直观:
package org.cc.vo;
import java.util.ArrayList;
import java.util.List;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
public class Main {
public static void main(String[] args) {
XStream x=new XStream();
// XStream x = new XStream(new JettisonMappedXmlDriver());
x.processAnnotations(Person.class);
Person p=new Person();
p.setAge(30);
List fa=new ArrayList();
fa.add("游戏");
fa.add("上网");
p.setFavor(fa);
p.setName("cc");
String info=x.toXML(p);
System.out.println(info);
Person p2=(Person)x.fromXML(info);
System.out.println(p2);
}
}
输出:
Xml代码
30
false
游戏
上网
Person [name=cc, age=30, sex=false, favor=[游戏, 上网], tempid=0]
注意了以上代码注释掉的那块打开 并把没有参数的构造方法的XStream那一段注释掉产生的就是JSON(换了一个引擎)
产生内容如下:
{"Person":{"@name":"cc","age":30,"sex":false,"favor":["游戏","上网"]}}
Person [name=cc, age=30, sex=false, favor=[游戏, 上网], tempid=0]