XStream的基本使用
先准备两个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