Как пометить свойство как переходное в Javabean, чтобы избежать сериализации XMLEncoder? - PullRequest
4 голосов
/ 11 января 2012

Использование ключевого слова «transient» в объявлении переменной или «@Transient» в получателе не останавливает сериализацию свойств XMLEncoder.Единственный способ сообщить XMLEncoder не сериализовать определенные свойства - это с помощью кода вроде:

BeanInfo info = Introspector.getBeanInfo(MyClass2.class);
PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; ++i) {
    PropertyDescriptor pd = propertyDescriptors[i];
    if (pd.getName().equals("props")) {
        pd.setValue("transient", Boolean.TRUE);
    }
}

Действительно ???Есть ли более простой способ, который не требует кода во время выполнения для обхода всех свойств?Что-то вроде модификатора переходного процесса будет качаться!

Вот JavaBean, который будет иметь все свои свойства, сериализованные XMLEncoder, несмотря на использование «переходного»:программа:

<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_29" class="java.beans.XMLDecoder"> 
 <object class="TestJavaBeanSerialization"> 
  <void property="myProp1"> 
   <string>prop 1</string> 
  </void> 
  <void property="myProp2"> 
   <string>prop 2</string> 
  </void> 
 </object> 
</java> 

ОБНОВЛЕНИЕ

Я до сих пор не получил окончательного ответа на исходный вопрос.Есть эта статья, на которую люди продолжают ссылаться, но она не ясна, и никто не дал ссылку на API или спецификацию, в которой четко указывается, что единственный способ пометить свойство как переходный - это пройти по всем свойствам и вызвать setValue.*

Ответы [ 6 ]

1 голос
/ 03 декабря 2015

Вы используете неправильный @ Переходный

Следует использовать java.beans.Transient для аннотации. javax.persistence.Transient учитывается только в контексте постоянства базы данных, а не сериализации BeanInfo.

1 голос
/ 17 сентября 2015

Я привык использовать это известное решение в течение нескольких лет в моем собственном коде , но с Java 1.7 есть гораздо более простой вариант: java.beans.Переходная аннотация .Обратите внимание, что вы можете использовать его в методах получения и установки, но не в полях в отличие от javax.persistence.Transient (JPA).

import java.beans.Transient;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;

public class Test {

public static final void main(String[] args) throws Throwable {
    final Capsule caps = new Capsule();
    caps.setIdentifier("6545346");
    caps.setMe("Julien");
    caps.setSentences(new ArrayList<>(Arrays.asList(new String[]{"I don't like my job","I prefer sleeping"})));
    try (FileOutputStream fOut = new FileOutputStream(new File(System.getProperty("user.home"), "test.xml")); 
         BufferedOutputStream out = new BufferedOutputStream(fOut);
         XMLEncoder encoder = new XMLEncoder(out)) {
        encoder.writeObject(caps);
        encoder.flush();
    }
}

public static final class Capsule {

    private String identifier;

    private transient String me;

    private transient ArrayList<String> sentences;

    public Capsule() {
        super();
    }

    @Transient
    public ArrayList<String> getSentences() {
        return sentences;
    }

    @Transient
    public void setSentences(ArrayList<String> sentences) {
        this.sentences = sentences;
    }

    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    @Transient
    public String getMe() {
        return me;
    }

    @Transient
    public void setMe(String me) {
        this.me = me;
    }
}}

Результат:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_76" class="java.beans.XMLDecoder">
 <object class="Test$Capsule">
  <void property="identifier">
   <string>6545346</string>
  </void>
 </object>
</java>

Обратите внимание на отсутствие переходных значений. Я не мог пропустить коллекции в 2009 , но, похоже, сейчас работает.

1 голос
/ 07 сентября 2015

У меня была похожая проблема, и я искал более простое решение. Я справился с этим, нарушив соглашения Java Beans.

Если вы не хотите сериализовать поле, не устанавливайте для него методы получения. Вместо «get» и «set» используйте другие префиксы, такие как «retrieve» и «save». Например -

int x=0;
public int retrieveX() {
    return x;
}
public void saveX(int x) {
    this.x = x;
}

Это помогло мне, и я уверен, что поможет другим, которым не нужны соглашения Java Beans в коде. Использование этого способа делает переменную доступной в вашем приложении, но в то же время скрывает ее от сериализатора XMLEncoder.

Надеюсь, это поможет кому-то в будущем.

1 голос
/ 27 июля 2012

Обходной путь может заключаться в использовании JAXB в качестве вашего XML-сериализатора, который связан с Java 1.6. Он поддерживает аннотацию @ XmlTransient .

1 голос
/ 11 января 2012

это единственный способ объявить свойства временным. Вы можете увидеть статью. URL-адрес http://www.oracle.com/technetwork/java/persistence4-140124.html?ssSourceSiteId=otncn#transient

0 голосов
/ 11 января 2012

в поле myProp1 добавьте статические и удалите ключевые слова '@Transient' перед методом getMyProp1, затем запустите программу ,, и в результате вы захотите?

...