How do you mark a property as transient in javab to avoid serialization with XMLEncoder?

Using the "transient" keyword in a variable declaration or "@Transient" on a getter does not stop XMLEncoder from serializing properties. The only way I can say that XMLEncoder does not serialize certain properties is with code like:

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

Really??? Is there an easier way that does not require code execution while all the properties are executing? Something like a transition modifier will swing!

Here's a JavaBean that will have all the properties serialized by XMLEncoder, despite using a "transient":

 import java.io.Serializable; import java.beans.XMLEncoder; public class TestJavaBeanSerialization implements Serializable { public TestJavaBeanSerialization() {} private transient String myProp1 = null; private String myProp2 = null; @Transient public String getMyProp1() { return myProp1; } public void setMyProp1(String a) { myProp1 = a; } public String getMyProp2() { return myProp2; } public void setMyProp2(String a) { myProp2 = a; } public static void main( String[] args ) { TestJavaBeanSerialization myObj = new TestJavaBeanSerialization(); myObj.setMyProp1("prop 1"); myObj.setMyProp2("prop 2"); XMLEncoder encoder = new XMLEncoder(System.out); encoder.writeObject(myObj); encoder.close(); } } 

Here's the output of this program:

 <?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> 

UPDATE

I still have not received a definitive answer to the original question. There is this article that people continue to refer, but it is not clear, and no one gave a link to the API or specification, which clearly states that the only way to mark a property as transient is to iterate over all the properties and call "setValue".

+4
source share
6 answers

this is the only way to declare transient.You properties can see the article. Url http://www.oracle.com/technetwork/java/persistence4-140124.html?ssSourceSiteId=otncn#transient

+1
source

A workaround would be to use JAXB as the XML serializer that comes bundled with Java 1.6. It supports @XmlTransient annotation.

+1
source

I had a similar problem and was looking for an easier solution. The way I did it was to break the Java Beans conventions.

If you do not want to serialize the field, do not set getter settings for it. Instead of get and set, use other prefixes such as retrieve and save. For instance -

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

This did the trick for me, and I'm sure it will help others who don't need Java Beans conventions in code. Using this method makes the variable available throughout the application, but at the same time hides it from the XMLEncoder serializer.

Hope this helps someone in the future.

+1
source

I used to use this well-known solution for several years in my own code , but there is much simpler one since Java 1.7: java.beans.Transient annotation . Please note that you can use it on getters and setters, but not on fields other than 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; } }} 

Result:

 <?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> 

Note the lack of transient values. I could not miss the collections in 2009 , but now it works.

0
source

You are using the wrong @Transient

Must use java.beans.Transient for annotation. javax.persistence.Transient is respected only in the context of saving the database, and not for serializing BeanInfo.

0
source

The myProp1 field adds static and deletes the keywords '@Transient' before the getMyProp1 method, and then runs the program, and the result is what you want?

-1
source

Source: https://habr.com/ru/post/1390347/


All Articles