xstream简介(bean与xml转换工具)

前端之家收集整理的这篇文章主要介绍了xstream简介(bean与xml转换工具)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
xstream简介(bean与xml转换工具)

本文
解决了"_"显示为"__"的问题。
解决了当xml的element属性多余bean的映射问题
解决生成xml换行的问题
作用:
能够简单的通过
xstreamInstance.fromXML(xmlContent); 获取到对象
xstreamInstance.toXML(beanInstance); 将对象转换为xml
官网:
http://xstream.codehaus.org/

适用场景
bean与xml存在相互转换的场景:配置文件读取,报文解析,生成报文
从官方的版本演进上看,还提供了hibernate,json配置文件的读取。从1.4版本以后,新加入hibernate相关处理的逻辑,该部分功能尚未详细了解。
不适用场景
xml文件较大(比如有个10M的xml文件解析,就不太适用,因一次性解析,以及生成对象将会造成内存溢出)
效率
经过实测对象10个属性,对应xml。
xstream采用默认xml引擎,效率是dom4j解析的10倍左右(具体效率与代码实现有关,dom4j也能实现较高性能的解析)
总体来说,利用xstream能够大大提高,xml解析的入门,以及编写方便
具体事例:
如何应用:
从xstream的pom文件分析
只需要将xstream.jar xpp3.jar xmlpull.jar放入项目即可
如果为maven项目
只需要添加
Java代码
  1. <dependency>
  2. <groupId>com.thoughtworks.xstream</groupId>
  3. <artifactId>xstream</artifactId>
  4. <version>1.4.3</version>
  5. </dependency>

使用实例:
例子一:
定义类
publicclassPerson{
  • privateStringfirstname;
  • privateStringlastname;
  • privatePhoneNumberphone;
  • privatePhoneNumberfax;
  • //...constructorsandmethods
  • }
  • classPhoneNumber{
  • privateintcode;
  • privateStringnumber;
  • }

  • 初始化解析对象
    XStreamxstream=newXStream();

    如果不想使用xpp作为xml解析引擎,也可写为new XStream(new Dom4jDriver());
    设置映射规则
    xstream.alias("person",Person.class);
  • xstream.alias("phonenumber",PhoneNumber.class);

  • 将对象序列化为xml
    Personjoe=newPerson("Joe","Walnes");
  • joe.setPhone(newPhoneNumber(123,"1234-456"));
  • joe.setFax("9999-999"));
  • Stringxml=xstream.toXML(joe);

  • 结果:
    <person>
  • <firstname>Joe</firstname>
  • <lastname>Walnes</lastname>
  • <phone>
  • <code>123</code>
  • <number>1234-456</number>
  • </phone>
  • <fax>
  • 9999-999</number>
  • </fax>
  • </person>

  • 由xml生成对象
    PersonnewJoe=(Person)xstream.fromXML(xml);

    当然xstream也支持注解,一下代码中使用到了 XstreamUtils 这个是在xstream基础上的封装,解决了现在xstream在日常使用中会出现的一些问题
    @XStreamAlias("TestBeanRoot")
  • classTestBean
  • {
  • privateStringtestEl1;
  • @XStreamAlias("test_Rename_El2")
  • privateStringtestEl2;
  • @XStreamAsAttribute
  • privateStringtestAttr;
  • @XStreamOmitField
  • privateStringtestSkip;
  • @XStreamImplicit(itemFieldName="itemName",keyFieldName="keyName")
  • privateList<String>testList;
  • ...getAndSet
  • XStreamtestBeanXstream=XstreamUtils.getXstream(XstreamUtilsTest.TestBean. XstreamUtilsTest.TestBeantt=createTestBean();
  • System.out.println(testBeanXstream.toXML(tt));
  • "<TestBeanRoottestAttr=\"attr\">"
  • "<testEl1>el1</testEl1>"
  • +"<test_Rename_El2>el2</test_Rename_El2>"
  • +"<itemName>listItem1</itemName>"
  • +"<itemName>listItem2</itemName>"
  • +"</TestBeanRoot>"

  • 如果存在多级el的情况,可以通过引用其他类的形式 如 private TestBean2 testBean2;,新的类内部又可以具有其他结构
    xstream常用的注解有:
    @XStreamAlias
  • @XStreamImplicit

  • 但看到很多文章,有这样的说法
    1、xstream有bug,在转换过程中,会将 定义别名中的下划线“_”转换为xml后会变成“__”
    2、在xml生成对象时,xml有多出来的元素时,对象生成将会抛出异常。
    事实上从xstream源代码分析,这两个都不是问题,xstream都提供了对应的处理方式
    具体参看工具类
    /**
  • *xstream工具封装
  • *用以处理xml与bean的转换
  • *
  • *@authorPengQingyang
  • *@version[版本号,2012-10-5]
  • *@see[相关类/方法]
  • *@since[产品/模块版本]
  • */
  • classXstreamUtils
  • staticLoggerlogger=LoggerFactory.getLogger(XstreamUtils.staticMap<Class<?>,XStream>xstreamMap=newWeakHashMap<Class<?>,XStream>();
  • *转换过程中特殊字符转码
  • staticNameCodernameCoder=newNameCoder()
  • publicStringencodeNode(Stringarg0)
  • returnarg0;
  • publicStringencodeAttribute(Stringarg0)
  • publicStringdecodeNode(Stringarg0)
  • publicStringdecodeAttribute(Stringarg0)
  • };
  • *在xml中多余的节点生成bean时会抛出异常
  • *通过该mapperWrapper跳过不存在的属性
  • *@parammapper
  • *@return[参数说明]
  • *@returnMapperWrapper[返回类型说明]
  • *@exceptionthrows[异常类型][异常说明]
  • *@see[类、类#方法、类#成员]
  • staticMapperWrappercreateSkipOverElementMapperWrapper(
  • Mappermapper)
  • MapperWrapperresMapper=newMapperWrapper(mapper)
  • *@paramelementName
  • *@return
  • @SuppressWarnings("rawtypes")
  • @Override
  • publicClassrealClass(StringelementName)
  • Classres=null;
  • ;
  • try
  • res=super.realClass(elementName);
  • catch(CannotResolveClassExceptione)
  • logger.warn("xstreamchangexmltoobject.filed(0)notexsit.",
  • elementName);
  • returnres;
  • returnresMapper;
  • *获取xstream转换对象
  • *@paramclassType
  • *@returnXStream[返回类型说明]
  • staticXStreamgetXstream(Class<?>classType)
  • returngetXstream(classType,true);
  • *@paramisSkipOverElement
  • staticXStreamgetXstream(Class<?>classType,85); font-weight:bold">booleanisSkipOverElement)
  • if(xstreamMap.containsKey(classType))
  • returnxstreamMap.get(classType);
  • XStreamres=if(isSkipOverElement)
  • newXStream(newXpp3DomDriver(nameCoder))
  • *@paramnext
  • protectedMapperWrapperwrapMapper(MapperWrappernext)
  • returncreateSkipOverElementMapperWrapper(next);
  • else
  • newXpp3DomDriver(nameCoder));
  • logger.info("createxstreamby{0},parameter{1}",85); font-weight:bold">newObject[]{
  • classType.getName(),isSkipOverElement});
  • res.processAnnotations(classType);
  • xstreamMap.put(classType,res);
  • 封装后的使用:
    staticxxxxXstream=XstreamUtils.getXstream(Xxxx. method(){
  • xxxxXstream.toXML
  • xxxxXstream.fromXML
  • 2012-10-22追加
    如果想生成的xml是否换行,自己进行控制,可这样写
    *<获取xstream转换对象>
  • *<功能详细描述>
  • *@paramisNewLine
  • booleanisSkipOverElement,85); font-weight:bold">booleanisNewLine){
  • if(xstreamMap.containsKey(classType)){
  • *生成domDriver重写createWriter方法,使生成的domDriver在新的节点不会信生成一行
  • HierarchicalStreamDriverdomDriver=if(isNewLine){
  • domDriver=newXpp3DomDriver(nameCoder);
  • }else{
  • newXpp3DomDriver(nameCoder){
  • publicHierarchicalStreamWritercreateWriter(Writerout){
  • returnnewPrettyPrintWriter(out,getNameCoder()){
  • protectedStringgetNewLine(){
  • return"";
  • if(isSkipOverElement){
  • newXStream(domDriver){
  • protectedMapperWrapperwrapMapper(MapperWrappernext){
  • newXStream(domDriver);
  • }
  • 猜你在找的XML相关文章