zoukankan      html  css  js  c++  java
  • XStream使用总结

    最近做webService报文转换的公共接口使用到了XSream工具库,写个小总结备忘。。。

        XStream是一个可以将javaBean与XML双向转换的java类库,本文内容基于xstream-1.4.4版本。所需maven依赖如下:

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

    1.基本使用方法

        new Xstream().toXML(bean);

        使用该方式转换的xml格式如下:

    <org.xstream.test.People>
        <age>10</age>
        <name>sedric</name>
     </org.xstream.test.People>

        该格式由完整类名作为根节点,类成员变量名及变量值组成xml元素内容。

    2.定义xml元素名、属性名别名

    普通方式:

    xstream.useAttributeFor(People.class,"age");
    xstream.useAttributeFor(People.class,"name");
    //定义Class别名
    xstream.alias("People", People.class);
    //定义Field别名
    xstream.aliasField("Age_Alias", People.class, "age");

    使用该方式转换的xml格式如下:

    <People Age__Alias="10" name="sedric"/>

    注解方式:

    @XStreamAlias("People")
    public class People {
    
    @XStreamAlias("Age_Alias")
    @XStreamAsAttribute
    private int age;
    
    @XStreamAsAttribute
    private String name;

    使用注解方式时必须指定xstream解析annotations,方式如下:

    //指定所有class均解析annotations
    xstream.autodetectAnnotations(true);
    //指定指定class解析annotations
    xstream.processAnnotations(People.class);

    3.xstream定义别名单下划线(_)双下划线(__)

    xstream默认的转换方式中定义了对特殊字符的转换,代码如下:

    //XmlFriendlyNameCoder.encodeName(String name)
    for (; i < length; i++ ) {
                char c = name.charAt(i);
                if (c == '$' || c == '_' || c <= 27 || c >= 127) {
                    break;
                }
     }

    xstream对以上范围字符进行特殊字符转换,导致单下划线变为双下划线。解决方式:

        方法1:str.replaceAll(“__“,“_“);

        方法2:

    //使用xstream自带的NoNameCoder构造xstream,该方式将导致所有特殊字符都不转义
    XStream xstream = new XStream(new XppDriver(new NoNameCoder()));
    //使用Domdriver及NonameCoder构造xstream,该方式可以指定xml编码方式
    XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));

        方法3:自定义NameCoder,对指定特殊字符进行转换。

    4.XStreamImplicit注解使用

        当需要将collection或map类型的成员变量中数据转换成xml相同层次的元素时,可以在该成员变量使用该注解。

    @XStreamImplicit(itemFieldName = "List_Element")
    private List<JP> jps;

    转换的xml如下:

    <People Age_Alias="10" name="sedric">
    <List_Element>
    <gender>man</gender>
    <reason>人傻钱多</reason>
    </List_Element>
    <List_Element>
    <gender>woman</gender>
    <reason>巧言令色</reason>
    </List_Element>
    </People>

        XStreamImplicit注解有两个属性:itemFieldName是指当前集合数据转换为xml元素时的 elementName;keyFieldName在集合元素为复杂对象时,会使用集合元素的成员变量名作为元素的elementName,当集合元素为 基本数据类型及String类型时,keyFieldName指定的值将作为元素的elementName。

    @XStreamImplicit(itemFieldName = "String_Element", keyFieldName = "String_Field")
    private List<String> stringList;
    
    @XStreamImplicit(itemFieldName = "List_Element", keyFieldName = "List_Field")
    private List<JP> jps;
    
    @XStreamImplicit(itemFieldName = "Map_Element", keyFieldName = "Map_Field")
    private Map<String, String> map;

    转换的xml如下:

    <People Age_Alias="10" name="sedric">
    <String_Element>str1</String_Element>
    <String_Element>str2</String_Element>
    <List_Element>
    <gender>man</gender>
    <reason>人傻钱多</reason>
    </List_Element>
    <List_Element>
    <gender>woman</gender>
    <reason>巧言令色</reason>
    </List_Element>
    <Map_Element>value2</Map_Element>
    <Map_Element>value1</Map_Element>
    </People>

    5.XStreamConverter注解使用

        xstreamConvert用于指定class及Field的converter(转换方式)。

        xstreamConvert定义于class时,该class及其所有成员变量(递归,即成员变量是复合对象时该符合对象的成员变量)均 默认使用xstreamConvert指定的converter进行转换(满足converter.canConvert(Class type)时一定会使用指定的converter)。

        xstreamConvert定义与field时,该field如果是基本类型或String类型,满足canConvert(Class type)方法时使用该converter进行转换;如果是复合对象,则该对象所有成员变量(递归)满足canConvert(Class type)时使用该converter进行转换。

    XStreamConverter注解属性:

    //priority指定converter优先级,即当有多个converter均可转换当前对象时,只使用priority
    //最大的converter。
    int priority() default XStream.PRIORITY_NORMAL;
    //以下属性在指定值时,将会在构造该converter时作为构造方法的参数传入。
    Class<?>[] types() default {};
    String[] strings() default {};
    byte[] bytes() default {};
    char[] chars() default {};
    short[] shorts() default {};
    int[] ints() default {};
    long[] longs() default {};
    float[] floats() default {};
    double[] doubles() default {};
    boolean[] booleans() default {};

    对于converter构造参数较复杂,上述属性不能满足构造参数时,可以使用xstream.registerConverter(参数。。)或xstream.registerLocalConverter(参数。。)来注册converter。

    6.xstream对泛型、接口、超类的支持

    对于复合类型对象,xstream默认使用ReflectionConverter来进行对象转换。该converter中定义了当属性定义类型与运行时类型不一致时,将会给该元素添加一个class属性。代码如下:

    @XStreamAlias("Generic")
    public class GenericTypeTest {
    
    @XStreamAlias("People")
    private People people;
    
              GenericTypeTest generic = new GenericTypeTest();
               //SB是People的子类,SB中定义成员变量
     SB sb = new SB(50, "sb");
    
     generic.setPeople(sb);

    转的xml如下:

    <Generic>
    <People class="org.xstream.test.SB" Age_Alias="50" name="sb">
    <gender>woman</gender>
    <reason>resson</reason>
    </People>
    </Generic>

    当转换xml不需要该class属性时,可以通过自定义converter实现。实现方式参照AbstractReflectionConverter.doMarshal方法,只需注释该方法中如下内容:

    Class defaultType = mapper.defaultImplementationOf(fieldType);
    if (!actualType.equals(defaultType)) {
    String serializedClassName = mapper.serializedClass(actualType);
    f (!serializedClassName.equals(mapper.serializedClass(defaultType))) {
    // String attributeName =
    // mapper.aliasForSystemAttribute("class");
    // if (attributeName != null) {
    // writer.addAttribute(attributeName,
    // serializedClassName);
    // }
    }
    }

    对于xml转javabean,xstream默认的所有converter均不支持泛型、接口。如果存在超类时,xml中存在子类属性时,转换将出现异常,不包含子类属性时,可转换成功。

    原文链接

    相关:XStream实用指南

  • 相关阅读:
    私有构造函数(C# 编程指南)
    unshift(), push(),shift(),pop()函数的运用
    flex转载
    二叉树各节点的实现
    关于删除树中指定节点的实例分析
    树的各种操作代码实现
    关于二叉查找树的++迭代器的实现
    利用map,以一个单词为键,以与它相差一个字母的单词组集作为值的算法编程
    逆向单项链表的算法
    给Vector类添加insert
  • 原文地址:https://www.cnblogs.com/langtianya/p/5029728.html
Copyright © 2011-2022 走看看