XStream简单入门
简单的讲,XStream 涉及的就五个知识点:详情参考 官网
混叠,注解,转换器,对象流和操作json!
下面就用几个简单的例子来实现上述五个知识点!
基本步骤:
第1步:创建XStream对象。
通过它传递一个StaxDriver创建XStream对象。StaxDriver使用SAX解析器(可从Java6),一个快速的XML解析器。
XStream xstream = new XStream(new StaxDriver());
第2步:序列化对象到XML。
使用toXML() 方法来获取对象的XML字符串表示。
//Object to XML Conversion
第3步:反序列化XML获得对象。
使用 fromXML()方法来从XML对象。
//XML to Object Conversion
例一:
通过实体生成xml
public class Student {
private String firstName;
private String lastName;
private int className;
private int rollNo;
private Address address;
public void setAddress(Address address) {
this.address = address;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setRollNo(int rollNo) {
this.rollNo = rollNo;
}
@Override
public String toString() {
return "Student{" +
"address=" + address +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", className=" + className +
", rollNo=" + rollNo +
'}';
}
}
public class Address
{
private String area;
private String city;
private String state;
private String country;
private int pincode;
public void setArea(String area) {
this.area = area;
}
public void setCity(String city) {
this.city = city;
}
public void setPincode(int pincode) {
this.pincode = pincode;
}
public void setState(String state) {
this.state = state;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("\nAddress [ ");
stringBuilder.append("\narea: ");
stringBuilder.append(area);
stringBuilder.append("\ncity: ");
stringBuilder.append(city);
stringBuilder.append("\nstate: ");
stringBuilder.append(state);
stringBuilder.append("\ncountry: ");
stringBuilder.append(country);
stringBuilder.append("\npincode: ");
stringBuilder.append(pincode);
stringBuilder.append(" ]");
return stringBuilder.toString();
}
}
public class Xstream_Test {
public static void main(String... args){
XStream xstream=new XStream(new DomDriver());
Student student=getStudentDetail();
// xstream.alias("student", Student.class);//生成开头的别名!!去掉全包名
String xml=xstream.toXML(student);
System.out.println(formatXml(xml));
}
private static Student getStudentDetail(){
Student student=new Student();
student.setFirstName("Mahesh");
student.setLastName("Parashar");
student.setRollNo(1);
Address address=new Address();
address.setArea("h.no. preet vihar.");
address.setCity("delhi");
address.setState("india");
address.setPincode(12211);
student.setAddress(address);
return student;
}
}
输出结果
发现输出,有类的包名
//类混叠是用来创建一个类的XML完全限定名称的别名。添加代码,去掉全包名
xstream.alias("student", Student.class);
再输出结果,com.it5.xstream_demo.xml_2.Student 就会被 student别名取代!!
如果要给student加属性那要咋办??看例二
例二
通过类混叠,字段混叠为类与字段创建别名及属性!
public class Student {
public String studentName;
public String age;
public List<Note> notes=new ArrayList<>();
public Student(String name,String age) {
this.studentName = name;this.age=age;
}
public void addNote(Note note) {
notes.add(note);
}
}
public class Note {
public String title;
public String description;
public Note(String title,String description) {
this.description = description;
this.title = title;
}
}
测试
public class Xstream_test_3 {
private static Student getStudentDetails() {
Student student=new Student("Mahesh","21");
student.addNote(new Note("first","my first name!"));
student.addNote(new Note("second","my second name!"));
return student;
}
public static void main(String... args) {
XStream xstream=new XStream(new DomDriver());
Student student=getStudentDetails();
//类混叠使用
xstream.alias("student", Student.class);
xstream.alias("note",Note.class);
//字段混叠使用
xstream.aliasField("name",Student.class,"studentName");
//属性混叠使用
xstream.aliasAttribute(Student.class,"studentName","name");
xstream.aliasAttribute(Student.class,"age","age");
//隐式集合混叠
xstream.addImplicitCollection(Student.class, "notes");
String xml=xstream.toXML(student);
System.out.println(XmlUtil.formatXml(xml));
}
}
我们发现三处好像与平时见过的xml不一样的地方!!红线标注了!
1,studentName 与 age 应作为student的属性
2.集合的名字不应出现
要想达到想要的效果,这里就出现三个概念
类混叠:表示在XML无需显示类的全包名。
属性混叠:表示在XML显示属性名。
隐式集合混叠:表示在XML无需显示集合根名。
添加如下代码如下;
//类混叠使用
xstream.alias("student", Student.class);
xstream.alias("note",Note.class);
//字段混叠使用
xstream.aliasField("name",Student.class,"studentName");
//属性混叠使用
xstream.aliasAttribute(Student.class,"studentName","name");
xstream.aliasAttribute(Student.class,"age","age");
或者
xstream.useAttributeFor(Student.class, "studentName");
//隐式集合混叠
xstream.addImplicitCollection(Student.class, "notes");
结果如下:
上面的代码中要去掉类全名,实现属性者都是手动自动配置,是不是觉得有点麻烦呀,接下来,就用注解来实现 上例!
@XStreamAlias("student") //定义类的别名
public class Student {
@XStreamAlias("name")//定义字段别名
@XStreamAsAttribute //定义字段是个属性名
public String studentName;
@XStreamImplicit //定义集合是个隐式的
public List<Note> notes = new ArrayList<>();
@XStreamOmitField //定义一个忽略的字段
private int type;
public Student(String studentName) {
this.studentName=studentName;
}
public void addNote(Note note) {
notes.add(note);
}
public void setType(int type) {
this.type=type;
}
}
在Note类名上加上
@XStreamAlias("note")
测试
public class XStream_test_4 {
public static void main(String... args) {
XStream xStream=new XStream(new DomDriver());
//通知框架来处理注解
xStream.processAnnotations(Student.class);
//或者
// xStream.autodetectAnnotations(true);
String xml=xStream.toXML(getSutentDetails());
System.out.println(XmlUtil.formatXml(xml));
}
private static Student getSutentDetails() {
Student student=new Student("Mans");
student.addNote(new Note("first","this first name"));
student.addNote(new Note("second","the second name"));
student.setType(1);
return student;
}
}
输出上例相同的结果!
对象流
XStream提供java.io.ObjectInputStream和java.io.ObjectOutputStream替代实现,使对象流可以被序列化或XML序列化。当大对象集要被处理,保持在存储器中的一个对象,这是特别有用的。
语法 : createObjectOutputStream()
ObjectOutputStream objectOutputStream = xstream.createObjectOutputStream(new FileOutputStream("test.txt"));
语法 :createObjectInputStream()
ObjectInputStream objectInputStream = xstream.createObjectInputStream(new FileInputStream("test.txt"));
对象流测试代码
public class XStream_test_5 {
public static void main(String... args) {
XStream mXStream = new XStream(new DomDriver());
mXStream.autodetectAnnotations(true);
Student student1=new Student("ma0","ss0");
Student student2=new Student("ma1","ss1");
Student student3=new Student("ma2","ss2");
Student student4=new Student("ma3","ss3");
try {
ObjectOutputStream os=mXStream.createObjectOutputStream(new FileOutputStream("text.txt"));
os.writeObject(student1);
os.writeObject(student2);
os.writeObject(student3);
os.writeObject(student4);
os.writeObject("Hello World!");
os.close();
ObjectInputStream in=mXStream.createObjectInputStream(new FileInputStream("text.txt"));
Student student5= (Student) in.readObject();
Student student6= (Student) in.readObject();
Student student7= (Student) in.readObject();
Student student8= (Student) in.readObject();
String txt= (String) in.readObject();
System.out.println(student5);
System.out.println(student6);
System.out.println(student7);
System.out.println(student8);
System.out.println(txt);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
@XStreamAlias("student")
public class Student {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return "Student{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
结果如下 :
Json操作
实体类,还是用上面的Student类
测试代码:
public class XStream_test_6 {
public static void main(String... args) {
XStream xStream=new XStream(new JsonHierarchicalStreamDriver(){
@Override
public HierarchicalStreamWriter createWriter(Writer out) {
return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);
}
});
Student student=new Student("ss","ssss");
xStream.setMode(XStream.NO_REFERENCES);
xStream.alias("student",Student.class);
System.out.println(xStream.toXML(student));
}
}
结果如下:
通过上述例子看XStream在解释xml是非常的方便,转换器主要是能改变xml文件的字段名
更多详解,请看官网!
综合例子:
解释如下xml文件:为方便就另保存在 xml.txt文件中
<?xml version="1.0" encoding="utf-8"?>
<alipay>
<is_success>T</is_success>
<request>
<param name="_input_charset">utf-8</param>
<param name="service">single_trade_query</param>
<param name="partner">20889010000000</param>
<param name="out_trade_no">7_20130223150319_26</param>
</request>
<response>
<trade>
<total_fee>0.01</total_fee>
<trade_no>2013022356736989</trade_no>
<trade_status>TRADE_SUCCESS</trade_status>
<use_coupon>F</use_coupon>
</trade>
</response>
<sign>6c472babf7bd98ascb97fee1666a3303</sign>
<sign_type>MD5</sign_type>
</alipay>
写实体如下
@XStreamAlias("alipay")
public class Alipay {
private String is_success;
private String sign;
private String sign_type;
public Request request;
public Response response;
@Override
public String toString() {
return "Alipay{" +
"is_success='" + is_success + '\'' +
", sign='" + sign + '\'' +
", sign_type='" + sign_type + '\'' +
", request=" + request +
", response=" + response +
'}';
}
}
@XStreamAlias("request")
class Request{
// @XStreamImplicit(itemFieldName = "param")
@XStreamImplicit(itemFieldName = "param")
public List<Param> params;
public Request(List<Param> params) {
this.params = params;
}
@Override
public String toString() {
return "Request{" +
"param=" + params +
'}';
}
}
@XStreamAlias("trade")
class Trade{
private String total_fee;
private String trade_no;
private String trade_status;
private String use_coupon;
@Override
public String toString() {
return "Trade{" +
"total_fee='" + total_fee + '\'' +
", trade_no='" + trade_no + '\'' +
", trade_status='" + trade_status + '\'' +
", use_coupon='" + use_coupon + '\'' +
'}';
}
}
/**
* ToAttributedValueConverter 取得value值
* 解释格式 如 <param name="_input_charset">utf-8</param>
* 用@XStreamConverter(value=ToAttributedValueConverter.class, strings={"param"})
* strings={"param"}中的param来接收xml中param中的值utf-8
*/
//@XStreamAlias("param")
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"param"})
class Param{
@XStreamAsAttribute()
private String name;
public String param;
@Override
public String toString() {
return "Param{" +
"name='" + name + '\'' +
", param='" + param + '\'' +
'}';
}
}
@XStreamAlias("response")
class Response{
private Trade trade;
@Override
public String toString() {
return "Response{" +
"trade=" + trade +
'}';
}
}
测试代码如下:
public class XStrem_alipay {
public static void main(String... args) {
try {
Alipay alipay= XmlUtil.toBeanFromFile("xml.txt",Alipay.class);
System.out.println(alipay);
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:toBeanFromFile是把xml转换成实体对象的方法,比较简单,综合来看XStream来解释xml是非常的方便,其中要注意的地方是这种 <param name="_input_charset">utf-8</param>
要使用转换器来获取param中的Value,还好框架已实现了,只要在类中加上@XStreamConverter(value=ToAttributedValueConverter.class, strings={"param"})
该注解,一切都变得很容易!!