Я пытаюсь сериализовать некоторые 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>
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);
JavaBeanConverter
использует методы вместо полей? Пожалуйста, попробуйте установитьtransient
поля.@Transient
на поле. Я пытался использовать@XStreamOmit
но это тоже не сработало. Понятия не имею, что здесь происходит.