¿Cómo usar la anotación @Transient cuando se usa JavaBeanConverter en XStream?

I am trying to serialise some POJOs to XML. Some of them use @Transient annotations to indicate that some properties should not be serialised.

I have made a small test case to demonstrate the problem. I have also tried using @XStreamOmit but the result is the same. I do NOT expect to see the HiddenTop property in the output.

The 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;
    }
}

El principal:

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();
        }
    }
}

La salida

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

preguntado el 28 de mayo de 14 a las 14:05

¿Crees que el JavaBeanConverter use the methods instead of the fields? Please try to set the fields transient. -

@Vertex - it is not possible to set @Transient on a field. I tried using @XStreamOmit but that didn't work either. No idea what's going on here. -

quiero decir transient (Java syntax) instead of @Transient (annotation). I've took a look into the source of JavaBeanConverter and I think there is no way prevent from serialization. It uses a JavaBeanProvider that supports to get a list of all serializable properties. It tests with p.getReadMethod() != null && p.getWriteMethod() != null if its serializable. The JavaBeanConverter iterate over these properties and serialize it, if mapper.shouldSerializeMember(definedIn, name) devoluciones true. DefaultMapper.shouldSerializeMember alway returns true. -

@Vertex - sorry about that. No, transient makes no difference. I just had a look at the code too and agree that is seems that JavaBeanConverter ignora @Transient -

1 Respuestas

Porque JavaBeanProvider no respeta la @Transient annotation a solution is to implement you own JavaBeanProvider that respect this annotation:

    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;
        }
    }

Puede usarlo de la siguiente manera:

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

contestado el 28 de mayo de 14 a las 15:05

unfortunately, this solution interferes with the ignoreUnknownElements action. - paul

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.