XStream Converter上下文convertAnother丢失属性

时间:2018-09-28 09:38:18

标签: java xstream

使用 XStream 1.4.10 ,我正在尝试实现一个自定义转换器来处理多态。为此,我实施了一个小型测试程序。除未设置派生类型的属性外,解组工作按预期进行。我在调试器上花费了很多时间,似乎在context.convertAnother()的最深处,它认为它看到了一个开始标记,并丢弃了这些属性!

Sample XML
<person>
    <name>Steve</name>
    <fubar>33</fubar>
    <cat stray="false" sheds="a lot" >
        <name>Gypsy</name>
        <nobble>nob</nobble>
    </cat>
</person>

域类

@XStreamAlias("person")
public class Person {
    public String name ;

    public int fubar ;

    @XStreamAsAttribute
    public int bar ;

    public Pet pet ;

    public Elephant elephant ;

    @Override
    public String toString() {
        return "Person [name=" + this.name + ", fubar=" + this.fubar + ", bar=" + this.bar + ", pet=" + this.pet + ", " + this.elephant + "]";
    }
}


    class Pet
    {
        public String name ;

    }

@XStreamAlias("dog")
class Dog extends Pet
{
    String breed ;

    @Override
    public String toString() {
        return "Dog [breed=" + this.breed + ", name=" + this.name + "]";
    }

}

@XStreamAlias("cat")
class Cat extends Pet
{
    @XStreamAsAttribute
    @XStreamAlias("stray")
    Boolean stray ;

    @XStreamAsAttribute
    @XStreamAlias("sheds")
    String sheds ;

    String nobble ;

    @Override
    public String toString() {
        return "Cat [stray=" + this.stray + ", name=" + this.name + ", nobble=" + this.nobble + ", sheds=" + this.sheds + "]";
    }
}

转换器(未实施编组!)

public class CustomConverter implements Converter {

    private List<Field> fields ;

    public CustomConverter()
    {
        this.fields = new ArrayList<>() ;

        for (final Field field : Person.class.getFields()) {
            if ((field.getModifiers() & Modifier.TRANSIENT) == 0) {
                field.setAccessible(true);
                this.fields.add(field) ;
            }
        }
    }

    @Override
    public void marshal(Object source, HierarchicalStreamWriter writer,
            MarshallingContext context) {
    }

    protected boolean setField(UnmarshallingContext context, Person person, String node, String value)
    {
        for (final Field field : this.fields) {
            if (field.getName().equals(node)) {
                try {
                    if (field.getType() == Integer.TYPE) {
                        field.set(person, Integer.valueOf(value));
                    }
                    else if (field.getType() == String.class) {
                        field.set(person, value) ;
                    }
                    else {  // try an object

                        final Object valueObject = context.convertAnother(person, field.getType()) ;
                        field.set(person, valueObject);
                    }
                    System.out.println("set "+ node);
                    return true ;
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                    System.err.println("can't set " + node);
                    return false ;
                }
            }
        }
        return false ;
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {

        final Person person = new Person() ;

        while (reader.hasMoreChildren()) {

            reader.moveDown();

            final String node = reader.getNodeName() ;

            if (!setField(context, person, node, reader.getValue())) {
                if ("cat".equals(node)) {
                    person.pet = (Pet) context.convertAnother(person, Cat.class);
                }
                else if ("dog".equals(node)){
                    person.pet = (Pet) context.convertAnother(context.currentObject(), Dog.class);
                }
            }

            reader.moveUp();
        }

        return person ;
    }

    @Override
    public boolean canConvert(Class type) {
        return type.equals(Person.class);
    }

}

结果(猫的属性(stray, sheds)null

set name
set fubar
Person [name=Steve, fubar=33, bar=0, pet=Cat [stray=null, name=Gypsy, nobble=nob, sheds=null], null]

此外,如果我向该人添加大象,则会出现一个例外,即属性必须位于开始标记上,但这是另一个问题。

0 个答案:

没有答案