先准备两个bean
1 public class Book { 2 private int bookId; 3 private String bookName; 4 private String bookCode; 5 6 ...(get和set方法省略) 7 }
public class BookShelf { private int number; private List<Book> books; private String remark; private Date date; public BookShelf(){ books=new ArrayList<Book>(); } ...(get和set方法省略) }
使用
1 Book book1=new Book(); 2 book1.setBookCode("001"); 3 book1.setBookId(1); 4 book1.setBookName("java编程"); 5 Book book2=new Book(); 6 book2.setBookCode("002"); 7 book2.setBookId(2); 8 book2.setBookName("jsp编程"); 9 BookShelf bookShelf=new BookShelf(); 10 bookShelf.setNumber(1); 11 bookShelf.setRemark("第一个书架"); 12 bookShelf.getBooks().add(book1); 13 bookShelf.getBooks().add(book2); 14 bookShelf.setDate(new Date()); 15 16 XStream xStream=new XStream(new DomDriver()); 17 String str= xStream.toXML(bookShelf); 18 System.out.println(str);
输出结果:
<xml.BookShelf>
<number>1</number>
<books>
<xml.Book>
<bookId>1</bookId>
<bookName>java编程</bookName>
<bookCode>001</bookCode>
</xml.Book>
<xml.Book>
<bookId>2</bookId>
<bookName>jsp编程</bookName>
<bookCode>002</bookCode>
</xml.Book>
</books>
<remark>第一个书架</remark>
<date>2014-07-04 07:03:34.485 UTC</date>
</xml.BookShelf>
输出的结果里,类名转换为节点名,但前面多了个xml(不爽),时间格式字符串也不爽,那下面就来改造一下吧!
1、先处理一下时间格式问题,这个需要我们自己定义date类型的字段要怎么转换,当然xstream为我们提供了接口,实现它吧
public class MuConverter implements Converter { //判断字段是否属于要转换的类型 @Override public boolean canConvert(Class paramClass) { return Date.class.isAssignableFrom(paramClass); } //对象转化为xml @Override public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) { SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); writer.setValue(format.format(object)); } //xml转化为对象 @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { try { Date date= DateFormat.getInstance().parse(reader.getValue()); return date; } catch (ParseException e) { return null; } } }
2、为各字段换个名字
xStream.alias("BookShelf", BookShelf.class);
xStream.alias("Book", Book.class);
//修改节点名称
xStream.aliasField("other", BookShelf.class,"remark");
//字段不做为节点,而是属性
xStream.aliasAttribute(Book.class, "bookId", "id");
xStream.useAttributeFor(Book.class, "bookId");
//去掉集体节点的父节点
//xStream.addImplicitCollection(BookShelf.class, "books");
//自定义转换器
xStream.registerConverter(new MuConverter());*/
输出结果
<BookShelf>
<number>1</number>
<books>
<Book id="1">
<bookName>java编程</bookName>
<bookCode>001</bookCode>
</Book>
<Book id="2">
<bookName>jsp编程</bookName>
<bookCode>002</bookCode>
</Book>
</books>
<other>第一个书架</other>
<date>2014-07-04</date>
</BookShelf>
3、如果觉得上面的指定代码太复杂了,也可以使用注解来实现
首先来看两个bean
@XStreamAlias("Book")
public class Book {
@XStreamAlias("id")
@XStreamAsAttribute
private int bookId;
private String bookName;
private String bookCode;
...
}
@XStreamAlias("BookShelf")
public class BookShelf {
private int number;
//去掉集体节点的父节点
//@XStreamImplicit
private List<Book> books;
private String remark;
@XStreamConverter(MuConverter.class)
private Date date;
public BookShelf(){
books=new ArrayList<Book>();
}
...
}
没有注解的字段按字段名默认来转换
直接调用方法即可
xStream.autodetectAnnotations(true); //也可以分别调用 //xStream.processAnnotations(BookShelf.class); //xStream.processAnnotations(Book.class);
上面的是对象转换为xml,现在来实现xml转换为对象,很简单(注意:xml转换成对象,需要通过上面的别名或注解的方式来指明转换,不能直接调用下面的代码)
XStream xStream=new XStream(new DomDriver()); xStream.autodetectAnnotations(true); BookShelf bookShelf2=(BookShelf)xStream.fromXML(str);
序列化和反序列化支持
不多说,直接上代码
1、反序列化
ObjectInputStream input=xStream.createObjectInputStream(inputStream);
BookShelf bookShelf=(BookShelf)input.readObject();
2、序列化
ObjectOutputStream out=xstream.createObjectOutputStream(outputStream);
out.writeObject(bookShelf);
out.close();
3、PrettyPrintWriter、CompactWriter
这两个是XStream自带的用于输出xml文件,区别在于后者输出的xml是连接的,前者输出的是有格式的xml