XStream学习总结
1 作用:
1.1 将一个对象直接序列化为XML文档类型的字符串,类名为父节点,类属性为子节点。
例如:
<student>
<name></name>
<age></age>
</student>
如果没有给类名和属性别名,类名显示类的包名称,属性和类属性字段一样。
因此别名使用请看下面。
1.2 将XML文档类型的字符串反序列化成对象,前提XML符合W3标准。
2 使用指南
2.1 实例化XStream
XStream xs = new XStream();
可以设置XML的解析方式,默认使用的是new XppDriver()驱动解析XML,XPP3是一种运行效率非常高的XML全解析实现,但依赖XPP包.
其他的有Dom4JDriver、DomDriver、StaxDriver等等。
2.2 为类设置别名
public void alias(String name, Class type)
参数:name为节点的别名,type为节点的类型即命名的类
2.3 为类属性设置别名
public void aliasField(String alias, Class definedIn, String fieldName)
参数:alias为别名,definedIn为要命名的类型,fieldName为要命名的属性
2.4 为包设置别名
public void aliasPackage(String name, String pkgName)
参数:name为包别名,pkgName命名的包
2.5 为节点属性设置别名
public void aliasAttribute(String alias, String attributeName)
参数:alias为别名,attributeName为要命名的属性
2.6 增加节点属性
public void useAttributeFor(Class definedIn, String fieldName)
参数:definedIn增加属性的类(节点),增加属性的名称。
2.7 隐藏类某个属性
public void omitField(Class definedIn, String fieldName)
2.8 隐藏集合父节点(必须是集合)
public void addImplicitCollection(Class ownerType, String fieldName)
2.9 将object对象转化为XML
String xml = xs.toXML( object )
2.10 将XML反序列化为对象
Object o = xs.fromXML( xml )
3 高级特性
3.1 XStream的模式:
在Java中经常会碰到对象引用的情况,如定义了一个对象A,B对象会引用对象A。那么在对象引用发生时,在序列化的XML中该如何表述呢?
XStream在XML中能够通过相对XPath、绝对XPath或者IDs模式表示对象之间的引用关系。模式可以通过方法setMode(int)来更改。通过引用可以简短XML代码量,避免冗余,但是降低了可阅读性。
l XStream.XPATH_RELATIVE_REFERENCES(默认) 默认的引用方式,通过XPath的相对位置来引用
2 XStream.XPATH_ABSOLUTE_REFERENCES 绝对引用方式
3 XStream.ID_REFERENCES ID引用方式,通过对元素编号来引用
4 XStream.NO_REFERENCES 无引用方式
3.2 代码示例:
XStream xs = new XStream();
xs.setMode( XStream.NO_REFERENCES );//设置对象引用模式
xs.registerConverter( new OtherFeeConver() );//注册转换器
xs.alias( Constant.NODE_NAME_SIEBELMESSAGE, SiebelMessage.class );
xs.useAttributeFor( Student.class, Constant.ATTR_XMLNS );
xs.useAttributeFor( Student.class, Constant.ATTR_XSI );
xs.useAttributeFor( Student.class, Constant.ATTR_SCHEMALOCATION );
xs.aliasAttribute( Student.class, Constant.ATTR_XSI, Constant.ATTR_XMLNS_XSL );
xs.aliasAttribute( Student.class, Constant.ATTR_SCHEMALOCATION, Constant.ATTR_XSI_SCHEMALOCATION );
3.3 注解方式:
@XStreamAlias("class")//注解别名
publicclass Dom {
@XStreamAsAttribute//注解该属性作为节点的属性
@XStreamAlias("名称")//使用别名
private String name;
@XStreamOmitField//隐藏该属性
privateint number;
@XStreamImplicit(itemFieldName ="Students")
private List<Student> students;
}
使用注解必须启用注解方式:xstream.autodetectAnnotations(true);
3.4 转换器
假如你对以下的结构无从下手,就可以使用它了。它可以处理更复杂的XML结构或其他的操作
<Student>
<key>...</key>
<value>...</value>
<key>...</key>
<value>...</value>
<key>...</key>
<value>...</value>
</Student>
先定义好转换器在注册:xs.registerConverter( new OtherFeeConver() )才能使用;
定义转化器:转换器可以申明Converter接口重写一下几个方法.
publicvoid marshal(Object obj, HierarchicalStreamWriter hierarchicalstreamwriter, MarshallingContext marshallingcontext);
该方法在将对象转换成XML之前调用执行,obj要转换的对象实例,HierarchicalStreamWriter是一个结构输出流,我们可以设置流的结构,我们可以像操作指针一样操作它,类的属性可以按该流制定的结构输出,对于输出特殊的XML结构很有效。MarshallingContext是正序列化上下文信息。
代码示例:
该方法将对象序列化为XML
public void marshal( Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2 )
{
Student stu = (Student)arg0;//将Object对象转化为要转化的对象
hierarchicalstreamwriter.startNode( startNode );//设置开始节点
hierarchicalstreamwriter.setValue( value );//设置值
hierarchicalstreamwriter.endNode(); //设置结束节点
//对象course为Student类的属性
arg1.startNode(startNode);
arg2.convertAnother( course );// 对象course为Student类的属性。序列化Student对象下的对象。如果Course类也注册了转换器,对Course解析时将调用转化器。
arg1.endNode();
}
该方法为反序列化,如果需要将XML再转化为对象需要实现该方法
public Object unmarshal(HierarchicalStreamReader hierarchicalstreamreader, UnmarshallingContext unmarshallingcontext);
参数HierarchicalStreamReader是输入流,读取XML结构转化成对象,我们可以像操作指针一样操作它,一定要关闭(moveDown()),UnmarshallingContext为反序列化上下文。
public Object unmarshal( HierarchicalStreamReader arg0, UnmarshallingContext arg1 )
{
Student stu = new Student;//反序列化时我们要实例化对象,设置值在返回。
while ( arg0.hasMoreChildren() )//读取的流中是否还有节点
{
arg0.moveDown();//arg0指针从首节点移到子节点
if ( “Name”.equalsIgnoreCase( arg0.getNodeName() ) )
{
stu.setName( arg0.getValue() );
}
arg0.moveUp();//arg0指针从子节点移到首节点,一定要的。相当于关闭
//对象course为Student类的属性
arg0.moveDown();
arg1.convertAnother(course);// 将course交给其他处理,就像拦截器放行
arg0.moveUp();
return stu;
}
确定需要使用该转换器的类,不可能所有的类都只是用一直转换器,指定某个类可以转换
boolean canConvert(Class class1);
代码示例:
public boolean canConvert( Class arg0 )
{
return arg0.equals( Student.class );
}
参考来源:http://xusweeter.iteye.com/blog/1064562