使用
pom依赖 1 2 3 4 5 6 <dependency > <groupId > com.thoughtworks.xstream</groupId > <artifactId > xstream</artifactId > <version > 1.3.1</version > </dependency >
输出xml 手动配置 Author 类
1 2 3 4 5 6 7 8 9 10 11 12 public class Author { private String name; public Author (String name) { this .name = name; } public String getName () { return name; } }
Entry 类
1 2 3 4 5 6 7 8 9 public class Entry { private String title, description; public Entry (String title, String description) { this .title = title; this .description = description; } }
Blog 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class Blog { private Author writer; private List entries = new ArrayList(); public Blog (Author writer) { this .writer = writer; } public void add (Entry entry) { entries.add(entry); } public List getContent () { return entries; } public static void main (String[] args) { Blog teamBlog = new Blog(new Author("qisheng.li" )); teamBlog.add(new Entry("first" , "first blog entry" )); teamBlog.add(new Entry("second" , "second blog entry" )); XStream xStream = new XStream(); System.out.println(xStream.toXML(teamBlog)); } }
输出的内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <com.air.xml.xstream.alias.Blog > <writer > <name > qisheng.li</name > </writer > <entries > <com.air.xml.xstream.alias.Entry > <title > first</title > <description > first blog entry</description > </com.air.xml.xstream.alias.Entry > <com.air.xml.xstream.alias.Entry > <title > second</title > <description > second blog entry</description > </com.air.xml.xstream.alias.Entry > </entries > </com.air.xml.xstream.alias.Blog >
默认输出的类,是fully qualified name,可以手动设置别名
1 2 3 xStream.alias("blog" , Blog.class ) ; xStream.alias("entry" , Entry.class ) ;
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <blog > <writer > <name > qisheng.li</name > </writer > <entries > <entry > <title > first</title > <description > first blog entry</description > </entry > <entry > <title > second</title > <description > second blog entry</description > </entry > </entries > </blog >
1 xStream.aliasField("author", Blog.class, "writter");
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <blog > <author > <name > qisheng.li</name > </author > <entries > <entry > <title > first</title > <description > first blog entry</description > </entry > <entry > <title > second</title > <description > second blog entry</description > </entry > </entries > </blog >
1 xStream.aliasPackage("aliased.pachage.name" , "com.air.xml.xstream.alias" );
输出的xml:
1 2 3 4 5 6 7 8 9 10 <aliased.pachage.name.Blog author ="qisheng.li" > <entry > <title > first</title > <description > first blog entry</description > </entry > <entry > <title > second</title > <description > second blog entry</description > </entry > </aliased.pachage.name.Blog >
Implicit Collections
implicit collection: whenever you have a collection which doesn’t need to display it’s root tag, you can map it as an implicit collection.
如果不想展示一个集合的root节点,比如上述的entries
,可以将其当做一个implicit collection
1 2 xStream.addImplicitCollection(Blog.class, "entries");
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 <blog > <author > <name > qisheng.li</name > </author > <entry > <title > first</title > <description > first blog entry</description > </entry > <entry > <title > second</title > <description > second blog entry</description > </entry > </blog >
可以看到entries
这个节点已经没有了
field输出为属性值 接着上面的例子,我们现在想让Blog的writer输出为Blog标签的属性值。
实现步骤:
1.创建一个转换器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class AuthorConverter implements SingleValueConverter { @Override public String toString (Object obj) { return ((Author) obj).getName(); } @Override public Object fromString (String str) { return new Author(str); } @Override public boolean canConvert (Class type) { return type.equals(Author.class ) ; } }
2.注册这个转换器
1 xStream.registerConverter(new AuthorConverter());
3.告诉XStream
1 2 3 4 5 xStream.useAttributeFor(Blog.class, "writer"); xStream.registerConverter(new AuthorConverter()); xStream.aliasField("author", Blog.class, "writer");
输出的xml:
1 2 3 4 5 6 7 8 9 10 <blog author ="qisheng.li" > <entry > <title > first</title > <description > first blog entry</description > </entry > <entry > <title > second</title > <description > second blog entry</description > </entry > </blog >
基于注解 主要使用的是XStreamAlias
注解来标记别名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @XStreamAlias ("message" )public class RendezvousMessage { @XStreamAlias ("type" ) private int messageType; public RendezvousMessage (int messageType) { this .messageType = messageType; } public static void main (String[] args) { XStream xStream = new XStream(); xStream.processAnnotations(RendezvousMessage.class ) ; RendezvousMessage rendezvousMessage = new RendezvousMessage(12 ); System.out.println(xStream.toXML(rendezvousMessage)); } }
xml 输出
1 2 3 <message > <type > 12</type > </message >
使用 @XstreamImplicit(itemFieldName = "xxx")
来处理
1 2 @XStreamImplicit (itemFieldName = "part" )private List<String> content;
1 2 3 4 5 <message > <type > 12</type > <part > first content</part > <part > second content</part > </message >
添加一个属性字段并指明他使用的转换器, 和一个基本类型——boolean
1 2 3 4 5 @XStreamConverter (value=BooleanConverter.class ) private boolean important ;@XStreamConverter (SingleValueCalendarConverter.class ) private Calendar created = new GregorianCalendar();
转化器代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class SingleValueCalendarConverter implements Converter { @Override public void marshal (Object source, HierarchicalStreamWriter writer, MarshallingContext context) { Calendar calendar = (Calendar) source; writer.setValue(String.valueOf(calendar.getTime().getTime())); } @Override public Object unmarshal (HierarchicalStreamReader reader, UnmarshallingContext context) { GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(new Date(Long.parseLong(reader.getValue()))); return calendar; } @Override public boolean canConvert (Class type) { return type.equals(GregorianCalendar.class ) ; } }
输出的xml结果:
1 2 3 4 5 6 7 <message > <type > 12</type > <part > first content</part > <part > second content</part > <important > false</important > <created > 1482856467282</created > </message >
1 2 3 @XStreamAlias ("type" )@XStreamAsAttribute private int messageType;
输出结果
1 2 3 4 5 6 <message type ="12" > <part > first content</part > <part > second content</part > <important > false</important > <created > 1482856554517</created > </message >
1 2 3 4 5 <message type ="12" > <part > first content</part > <part > second content</part > <created > 1482856661757</created > </message >
important
属性已经被隐藏
自动扫描注解 1 xStream.autodetectAnnotations(true );
xml转对象 1 2 3 4 5 RendezvousMessage deserializedMessage = (RendezvousMessage) xStream.fromXML("<message type=\"12\">\n" + " <part>first content</part>\n" + " <part>second content</part>\n" + " <created>1482859234272</created>\n" + "</message>" );
参考
About XStream
Alias Tutorial
Annotations Tutorial