一、基本使用

(1)Xstream介绍

    Xstream是一种OXMapping 技术,是用来处理XML文件序列化的框架,在将JavaBean序列化,或将XML文件反序列化的时候,不需要其它辅助类和映射文件,使得XML序列化不再繁索。Xstream也可以将JavaBean序列化成Json或反序列化,使用非常方便。

(2)Xstream的简单例子

pom.xml中引入xstream的依赖:

	<dependency>
	    <groupId>com.thoughtworks.xstream</groupId>
	    <artifactId>xstream</artifactId>
	    <version>1.4.10</version>
	</dependency>

 

javabean:

package zhao.domain;

public class Person {
	private String name;
	private int age;
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	@Override
	public String toString(){
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

测试类:

package zhao.test;

import org.junit.Test;

import zhao.domain.Person;

import com.thoughtworks.xstream.XStream;

public class AppTest {
	@Test
	public void test1(){
		Person bean=new Person("张三",19);
		XStream xstream = new XStream();
		System.out.println("xml与javabean之间的序列化和反序列化");
		//XML序列化
		String xml = xstream.toXML(bean);
		System.out.println(xml);
		//XML反序列化为javabean
		Person b=(Person)xstream.fromXML(xml);
		System.out.println(b);
	}
}

运行结果:

image.png

 

二、Xstream的别名

接上篇,还是那个Person类,我们来看下xstream的一些常用的别名是什么用法。

测试代码:

package zhao.test;

import org.junit.Test;

import zhao.domain.Person;

import com.thoughtworks.xstream.XStream;

public class AppTest {
	@Test
	public void test1(){
		Person bean=new Person("张三",19);
		XStream xstream = new XStream();
		//XStream的配置开始
		
		//在输出xml的时候使用model替换zhao.domain
		xstream.aliasPackage("model", "zhao.domain");
		//在输出xml的时候使用p替换zhao.domain.Person
		xstream.alias("p", Person.class);
		//输出xml的时候使用xingming显示name标签
		xstream.aliasField("xingming", Person.class, "name");
		//输出xml时把age当做属性
		xstream.useAttributeFor(Person.class, "age");
		System.out.println("xml与javabean之间的序列化和反序列化");
		//javabean序列化为xml
		String xml = xstream.toXML(bean);
		System.out.println(xml);
		//XML反序列化为javabean
		Person b=(Person)xstream.fromXML(xml);
		System.out.println(b);
	}
}

结果:

image.png

三、xstream涉及别名以及属性不对应情况的处理

先看下有这样一个xml配置文件名字叫做mapping.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<action path="/addBlack">
    <handleClass>
        com.roadjava.BlackSvcImpl
    </handleClass>
    <handleMethod>add</handleMethod>
    <requestClass>
        com.roadjava.BlackSvcImplAddRequest
    </requestClass>
    <returnClass>
        com.roadjava.BlackSvcImplAddResponse
    </returnClass>
</action>

我希望把xml转为如下的javabean:

package test01.beans;

public class ControllerBean {
    private String handleClass;
    private String handleMethod;
    private  String requestClass;
    private  String returnClass;
    private  String path;

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getHandleClass() {
        return handleClass;
    }

    public void setHandleClass(String handleClass) {
        this.handleClass = handleClass;
    }

    public String getHandleMethod() {
        return handleMethod;
    }

    public void setHandleMethod(String handleMethod) {
        this.handleMethod = handleMethod;
    }

    public String getRequestClass() {
        return requestClass;
    }

    public void setRequestClass(String requestClass) {
        this.requestClass = requestClass;
    }

    public String getReturnClass() {
        return returnClass;
    }

    public void setReturnClass(String returnClass) {
        this.returnClass = returnClass;
    }

    @Override
    public String toString() {
        return "ControllerBean{" +
                "handleClass='" + handleClass + '\'' +
                ", handleMethod='" + handleMethod + '\'' +
                ", requestClass='" + requestClass + '\'' +
                ", returnClass='" + returnClass + '\'' +
                '}';
    }
}

参照我之前介绍过的"Xstream的基本使用"以及“Xstream的别名”这两篇文章,我们要实现其转化很简单,如下:

package test01;
import com.thoughtworks.xstream.XStream;
import test01.beans.ControllerBean;
import java.io.InputStream;

public class TestApp {
    public static void main(String[] args) throws  Exception{
        InputStream is = TestApp.class.getClassLoader().getResourceAsStream("mapping.xml");
        XStream xStream=new XStream();
        xStream.alias("action",ControllerBean.class);
        xStream.useAttributeFor(ControllerBean.class,"path");
        ControllerBean cb= (ControllerBean) xStream.fromXML(is);
        System.out.println(cb);
    }
}

运行结果如下:

image.png

上面相当于复习与巩固了一下xstream的使用,我们来看下面遇到的问题在哪里?

修改mapping.xml加入一个标签:

<throwsEx>xxx</throwsEx>

因为现在xml和javabean不对应了,再次运行将报错:

Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field test01.beans.ControllerBean.throwsEx

---- Debugging information ----

message             : No such field test01.beans.ControllerBean.throwsEx

field               : throwsEx

class               : test01.beans.ControllerBean

required-type       : test01.beans.ControllerBean

converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter

path                : /action/throwsEx

line number         : 13

version             : 1.4.10

-------------------------------

at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.handleUnknownField(AbstractReflectionConverter.java:524)

at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:375)

at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:281)

at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)

at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:70)

at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)

at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)

at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)

at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)

at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1486)

at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1466)

at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1346)

at test01.TestApp.main(TestApp.java:13)

也就是我们要解决的问题是这样的:在xml 转 pojo 的时候 ,xml中多余的节点不需要转化到javabean中去。

怎么办呢?

修改构造xstream的方法即可:

XStream xStream=new XStream(){//相当于继承XStream并重写其wrapMapper方法
    @Override
    protected MapperWrapper wrapMapper(MapperWrapper next) {
        return  new MapperWrapper(next) {
            @Override
            //definedIn:在这里就是 test01.controller.ControllerBean的class对象,fieldName是解析出来的xml标签
            // 名字,比如path,returnClass,throwsEx等
            public boolean shouldSerializeMember(Class definedIn,String fieldName) {
                return definedIn != Object.class ? super.shouldSerializeMember(definedIn, fieldName) : false;
            }
        };
    }
};

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐