Xstream XML文件互转JAVA对象的利器

Xstream

公司给工具做个接口测试,工具返回给我们文件格式为xml,我们平台采用JAVA开发,为了今后的数据持久化 和 查看结果的方便,应该将XML转换为Object,这样接触到了XStream这个类库,虽然小,但功能着实强大。

网上有一篇灰常详细的文章对XStream进行介绍http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197.html,感谢博主。

另外这里对其进行一些补充,主要是在解析XML中遇到过一些不太符合常规的XML格式,这样就需要一些不同常规的处理方式来解决:


一、Converter接口的使用

话说有这么个响应文件需要进行解析

<Result value=\"Success\">

<EngineName>webxxx</EngineName>

<CPU>50</CPU>

<MEM>30</MEM>

<DISK>40</DISK>

<Funcs>

<Func name=\"木马扫描\">OK</Func>

<Func name=\"存储\">NO</Func>

</Funcs>

</Result>";

根据XML对应格式,可以将其解析成一个Result对象,其中包含engineName,cPU,mEM,dISK,List<Func>属性,其中Func对象对应<Func/>结点。按照普通的方法,无法将其中<Func/>结点的text值赋值给Func对象。

这时Converter就派上用场了:首先定义好各类

public class GetStateResult {
private String value;
        private String engineName;
        private String cPU;
private String mEM;
private String dISK;
private List<com.time.dbapp.vo.GetStateFunc> funcs;

public class GetStateFuc{

private String value;//对应 OK/NO

private String name;

Converter实现类

class RequestCoverter implements Converter{
public void marshal(Object arg0, HierarchicalStreamWriter writer,MarshallingContext context) {
}
public Object unmarshal(HierarchicalStreamReader reader,UnmarshallingContext context) {
com.time.dbapp.vo.GetStateFunc result = new com.time.dbapp.vo.GetStateFunc();
result.setName(reader.getAttribute("name"));  //获取顺序有关  必须先获取name,然后才能获取value,否则报错
result.setValue(reader.getValue());
return result;
}
public boolean canConvert(Class clazz) {
return clazz.equals(com.time.dbapp.vo.GetStateFunc.class);
}}

大概作用就是当解析到设置好的映射结点时(canConvert返回true表示),执行unmarshal方法去解析对应的结点

接下来进行XStream的配置:

               XStream xstream = new XStream();
xstream.registerConverter(new RequestCoverter());  //注册转换器
xstream.alias("result", GetStateResult.class);
xstream.alias("func", com.time.dbapp.vo.GetStateFunc.class);
xstream.useAttributeFor(com.time.dbapp.vo.GetStateFunc.class, "name");

这样就可以进行解析了!

二、XppDriver 、PrettyPrintWriter、XppReader类

我理解为一种解析输入输出驱动,该类继承AbstractXppDriver,实现了HierarchicalStreamDriver接口,(可以查看API文档)先看类中方法,就大概知道干嘛的了:

 XppDriver() {   
           public HierarchicalStreamWriter createWriter(Writer out) { }

        public HierarchicalStreamReader  createReader(Reader reader){}

大概猜到,我们可以在解析(Reader) 和 输出(Writer)进行一些操作了。这个在上面时候有这方面需要呢。问题是这么来的,测试工具返回给我们的文档结构中(如上)所有结点名称都为大写,但是按照JavaBean的命名规范,所有java属性应该以小写字母。当按照XStream处理原理,他们在实例化对象,并赋值的过程是没有通过GET/SET方法来的,直接操作属性,这样就会存在问题,一个大写一个小写是不能完成映射的。为了让代码既符合规范,又能正确解析XML文件。这样XppDriver闪亮登场。

通过API中XStream(HierarchicalStreamDriver hierarchicalStreamDriver)看到实例化XStream对象可以传递HierarchicalStreamDriver对象来处理。

所以我简单封装一下XStream

class RequestXStream {

RequestXStream(){

super(new XppDriver() {   
           public HierarchicalStreamWriter createWriter(Writer out) {   
               return new PrettyPrintWriter(out) {   
           public void startNode(String name){//将对应的属性名 转化成首字母大写
            super.startNode(StringUtil.upperFirstChar(name));
           } 
               };
           }
           public HierarchicalStreamReader  createReader(Reader reader){
            return new XppReader(reader){
            public String getNodeName(){
            return StringUtil.lowerFirstChar(super.getNodeName());{//将对应的属性名 转化成首字母小写
            }
            };
           }
});

}

}

这样就可以很好的处理结点首字母大小写的问题了,其中StringUtil.upperFirstChar为自己写的简单处理方法,将字符串首字母大写。当然针对不同的问题,可以实现XPPDriver具体不同方法,这些可以查看API,进行解决,总之XStream是个不错的类库,提供了丰富的接口,满足不同的文件格式解析和转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值