XStream JavaBeanConverter не сериализует свойства - PullRequest
4 голосов
/ 16 марта 2010

Попытка использовать JavaBeanConverter XStream и возникновение проблемы. Скорее всего, я упускаю что-то простое или недостаточно хорошо разбираюсь в обработке конвертера XStream.

@XStreamAlias("test")
public class TestObject
{
    private String foo;

    public String getFoo()
    {
        //return foo; -- Adjusted for EDIT#2
        return foo.toLowerCase();
    }

    public void setFoo(String foo)
    {
        this.foo = foo;
    }
}

public void test() throws Exception
{
    XStream x = new XStream(new XppDriver());
    x.autodetectAnnotations(true);
    x.processAnnotations(TestObject.class);

    x.registerConverter(new JavaBeanConverter(x.getMapper()));

    TestObject o = new TestObject();
    //o.setFoo("bar"); -- Adjusted for EDIT#2
    o.setFoo("BAR");

    String xml = x.toXML(o);

    System.out.println(xml);

    /*
      Expecting...
        <test>
          <foo>bar</foo>
        </test>

      But instead getting...
        <test>
          <foo/>
        </test>         
    */
}

Я попытался добавить трассировку для метода TestObject.getFoo(), и кажется, что он вызывается XStream, но данные не записываются в выходной поток.

После просмотра исходного кода JavaBeanConverter кажется, что моя реализация должна работать, что наводит меня на мысль, что я не настроил что-то правильно во время установки XStream.

Мне просто не хватает чего-то простого?

Спасибо!


Редактировать 1

Кроме того, если это поможет, я использую следующие Maven Deps для этого ...

<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.xstream</artifactId>
    <version>1.3_3</version>
</dependency>
<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.xpp3</artifactId>
    <version>1.1.4c_3</version>
</dependency>


Редактировать 2

Я изменил метод TestObject.getFoo(), чтобы лучше объяснить свою цель.

Я пытаюсь использовать методы получения / установки для "санации" данных внутреннего объекта. В частности, я пытаюсь очистить входящие десериализованные данные, стараясь избежать необходимости реализации метода readResolve () в Serializable.

Если бы я реализовал метод readResolve, мне пришлось бы выполнять очистку как в методе setter (для любого не десериализованного входящего набора данных в другом месте), так и в readResolve (для данных XML, которые я десериализовал).

Вот почему я использую JavaBeanConverter вместо нормальных полевых методов XStream ... для передачи данных через методы получения / установки.

Надеюсь, это объясняет немного лучше.

Спасибо.

Ответы [ 2 ]

4 голосов
/ 16 марта 2010

Пройдя по источнику XStream, вы можете найти его в com.thoughtworks.xstream.core.DefaultConverterLookup.

public Converter lookupConverterForType(Class type) {
    Converter cachedConverter = (Converter) typeToConverterMap.get(type);
    if (cachedConverter != null) return cachedConverter;
    Iterator iterator = converters.iterator();
    while (iterator.hasNext()) {
        Converter converter = (Converter) iterator.next();
        if (converter.canConvert(type)) {
            typeToConverterMap.put(type, converter);
            return converter;
        }
    }
    throw new ConversionException("No converter specified for " + type);
}

Вы заметите, что для String он возвращает JavaBeanConverter, и причина, по которой он это делает, заключается в том, что JavaBeanConverter будет использоваться для любого объекта с открытым конструктором по умолчанию (который имеет String).

Один из способов решения этой проблемы - дать JavaBeanConverter более низкий приоритет.

x.registerConverter(new JavaBeanConverter(x.getMapper()), -10);

Тогда JavaBeanConverter используется для вашего Бина, а SingleValueConverterWrapper используется для значения String.

2 голосов
/ 16 марта 2010

Если вы закомментируете строку

x.registerConverter(new JavaBeanConverter(x.getMapper()));

все работает отлично :) Я думаю, что вы выполняете обработку аннотаций и регистрируете конвертеры, когда достаточно одного из них

http://x -stream.github.io / аннотаций-tutorial.html

...