在XStream中使用JavaBeanConverter时如何使用@Transient注释?

时间:2014-05-28 13:52:56

标签: java annotations xstream pojo

我正在尝试将一些POJO序列化为XML。其中一些使用@Transient注释来指示某些属性不应序列化。

我做了一个小测试案例来证明这个问题。我也试过使用@XStreamOmit但结果是一样的。我不希望在输出中看到HiddenTop属性。

POJO:

package test;

import java.beans.Transient;
import com.thoughtworks.xstream.annotations.XStreamOmitField;

public class DerivedObject
{
    private String xVisible = "GOODTOP";
    private String xHidden = "BADTOP";

    public DerivedObject() {
    }

    public String getVisibleTop() {
        return xVisible;
    }

    public void setVisibleTop(String xVisible) {
        this.xVisible = xVisible;
    }

    @Transient
    public String getHiddenTop() {
        return xHidden;
    }

    @Transient
    public void setHiddenTop(String xHidden) {
        this.xHidden = xHidden;
    }
}

主要:

package test;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter;

public class TestAnnotation
{
    public static void main(String[] args) {
        DerivedObject o = new DerivedObject();
        o.setVisibleTop(":-)");
        o.setHiddenTop(":-(");
        try {
            XStream xs = new XStream();
            xs.autodetectAnnotations(true);
            xs.registerConverter(new JavaBeanConverter(xs.getMapper()),
                    XStream.PRIORITY_LOW);
            System.out.println(xs.toXML(o));
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出

<test.DerivedObject>
  <hiddenTop>:-(</hiddenTop>
  <visibleTop>:-)</visibleTop>
</test.DerivedObject>

1 个答案:

答案 0 :(得分:2)

Becouse JavaBeanProvider不尊重@Transient注释,解决方案是实现您尊重此注释的JavaBeanProvider

    public class TransientRespectingBeanProvider extends BeanProvider {
        @Override
        protected boolean canStreamProperty(PropertyDescriptor descriptor) {
            final boolean canStream = super.canStreamProperty(descriptor);
            if (!canStream) {
                return false;
            }

            final boolean readMethodIsTransient = descriptor.getReadMethod() == null
                    || descriptor.getReadMethod().getAnnotation(Transient.class) != null;
            final boolean writeMethodIsTransient = descriptor.getWriteMethod() == null
                    || descriptor.getWriteMethod().getAnnotation(Transient.class) != null;
            final boolean isTransient = readMethodIsTransient
                    || writeMethodIsTransient;

            return !isTransient;
        }
    }

您可以按如下方式使用它:

    final JavaBeanProvider beanProvider = new TransientRespectingBeanProvider();
    final Converter converter = new JavaBeanConverter(xstream.getMapper(), beanProvider);
    xstream.registerConverter(converter);