[英]XMLEncoder in java for serialization
Im just wondering how i use XMLEncoder
to serialize ArrayList<foo>
where foo is my own made class. 我只是想知道如何使用
XMLEncoder
序列化ArrayList<foo>
,其中foo是我自己的类。
Do i have to do anything in particular, ie define my own xml structure first and then call toString on each value in my list and write it out? 我是否必须做任何特别的事情,即首先定义我自己的xml结构,然后在列表中的每个值上调用toString并写出来?
Can anyone point me to a good tutorial? 谁能指点我一个好的教程? http://java.sun.com/products/jfc/tsc/articles/persistence4/ Thats what i have been looking at but it doesnt seem to mention what to do with non library classes.
http://java.sun.com/products/jfc/tsc/articles/persistence4/这就是我一直在看的东西,但它似乎没有提到如何处理非库类。
Thanks 谢谢
There is nothing special about serializing an ArrayList with XMLEncoder. 使用XMLEncoder序列化ArrayList没有什么特别之处。
Here is an example: 这是一个例子:
There is a bean class TestBean: 有一个bean类TestBean:
public class TestBean {
private String name;
private int age;
public TestBean() {
this.name = "";
this.age = 0;
}
public TestBean(String name, int age) {
this.name = name;
this.age = age;
}
// Getter and setter ...
@Override
public String toString() {
return String.format("[TestBean: name='%s', age=%d]", name, age);
}
}
And a class Main which serialize an ArrayList<TestBean>
and read it back again: 还有一个Main类,用于序列化
ArrayList<TestBean>
并再次读取它:
public class Main {
private static final String FILENAME = "testbeanlist.xml";
public static void main(String[] args) {
try {
// Create a list of TestBean objects ...
final List<TestBean> list = new ArrayList<TestBean>();
list.add(new TestBean("Henry", 42));
list.add(new TestBean("Tom", 11));
System.out.println("Writing list to file " + FILENAME + ": " + list);
// ... and serialize it via XMLEncoder to file testbeanlist.xml
final XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream(FILENAME)));
encoder.writeObject(list);
encoder.close();
// Use XMLDecoder to read the same XML file in.
final XMLDecoder decoder = new XMLDecoder(new FileInputStream(FILENAME));
final List<TestBean> listFromFile = (List<TestBean>) decoder.readObject();
decoder.close();
System.out.println("Reading list: " + listFromFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
And then the output is: 然后输出是:
Writing list to file testbeanlist.xml: [[TestBean: name='Henry', age=42], [TestBean: name='Tom', age=11]]
Reading list: [[TestBean: name='Henry', age=42], [TestBean: name='Tom', age=11]]
The toString()
method in TestBean
is only for pretty printing. TestBean
的toString()
方法仅适用于漂亮的打印。 It doesn't influence the XML serialization. 它不会影响XML序列化。
If you are looking for XML Serialization I would suggest you to go for XStream 如果您正在寻找XML序列化,我建议您选择XStream
Person joe = new Person("Joe", "Walnes");
joe.setPhone(new PhoneNumber(123, "1234-456"));
joe.setFax(new PhoneNumber(123, "9999-999"));
String xml = xstream.toXML(joe);
<person>
<firstname>Joe</firstname>
<lastname>Walnes</lastname>
<phone>
<code>123</code>
<number>1234-456</number>
</phone>
<fax>
<code>123</code>
<number>9999-999</number>
</fax>
</person>
XMLEncoder can be used for any classes, including user-defined ones- the article you mention does detail how to do this, but it is not very well written so it can be a little difficult to understand. XMLEncoder可以用于任何类,包括用户定义的类 - 您提到的文章详细说明了如何执行此操作,但它编写得不是很好,因此可能有点难以理解。
If your user-defined class follows the JavaBeans spec , then you can just use encoder.writeObject()
to serialize a List<Foo>
instance. 如果用户定义的类遵循JavaBeans规范 ,那么您可以使用
encoder.writeObject()
来序列化List<Foo>
实例。 This is because the XML output is just a series of instructions for how to recreate the given instance at runtime. 这是因为XML输出只是一系列有关如何在运行时重新创建给定实例的指令。 The default PersistenceDelegate knows how to serialize a List structure, but only has default behaviour for unknown classes.
默认的PersistenceDelegate知道如何序列化List结构,但只有未知类的默认行为。 By default it attempts to recreate a given object instance by calling its nullary (no-argument) constructor, and then setting its properties one by one to the values of the given instance- something guaranteed to be possible if the class is a JavaBean.
默认情况下,它会尝试通过调用其nullary(无参数)构造函数来重新创建给定的对象实例,然后将其属性逐个设置为给定实例的值 - 如果该类是JavaBean,则保证可以实现。
If your class has some properties that are read-only, ie they are set by the constructor and cannot be changed after construction time, then you have to do (slightly) more to get it to work. 如果你的类有一些只读的属性,即它们是由构造函数设置的,并且在构造时间之后无法更改,那么你必须(略微)更多才能使它工作。 You can create a custom instance of DefaultPersistenceDelegate which recognizes your class, and knows how to pass the appropriate data to its constructor- you simply pass it the names of the properties as a list, and it will do the rest:
您可以创建一个DefaultPersistenceDelegate的自定义实例来识别您的类,并知道如何将适当的数据传递给它的构造函数 - 您只需将属性的名称作为列表传递给它,它将完成剩下的工作:
PersistenceDelegate fooDelegate = new DefaultPersistenceDelegate(new String[] {"propertyName1", "propertyName2"});
encoder.setPersistenceDelegate(Foo.class, fooDelegate);
If your class has constructor arguments that do not directly map to properties with getter methods, and/or there are other complexities to restoring object state, you can generally work around these by extending PersistenceDelegate and implementing the necessary behaviour yourself. 如果您的类具有不使用getter方法直接映射到属性的构造函数参数,和/或还原其他复杂性来恢复对象状态,您通常可以通过扩展PersistenceDelegate并自己实现必要的行为来解决这些问题。 However, if your class is very complex to recreate at runtime and you want it to be serialized, you should seriously consider redesigning it to reduce its complexity- this will make the whole process much easier, and will vastly reduce the chance of errors, as well as making it easier to change and extend in future.
但是,如果您的类在运行时重新创建非常复杂并且希望将其序列化,那么您应该认真考虑重新设计它以降低其复杂性 - 这将使整个过程更加容易,并且将极大地减少出错的可能性,如以及将来更容易改变和扩展。
I'm not sure why so many examples on the internet are incomplete or don't work when it would only take a little attention for them to be much more useful. 我不确定为什么互联网上有这么多的例子是不完整的或不起作用的时候只需要注意它们就会更有用。 Here is a complete example that can be implemented in one file (PersonBean.java) and it works!
这是一个可以在一个文件(PersonBean.java)中实现的完整示例,它可以工作!
// This example creates two PersonBeans, creates an ArrayList, adds the beans to the
// list, serializes the ArrayList to an XML file.
// It then loads from the XML file into a new ArrayList
//
// Keywords: ArrayList, Serialize, XMLEncode, XMLDecode
// Note: Change the XML file while the 10 second Thread.sleep is waiting to see that
// the data is actually loaded from the file.
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.util.ArrayList;
public class PersonBean {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("[PersonBean: name='%s', age=%d]", name, age);
}
public static void main(String[] args) {
PersonBean person1 = new PersonBean();
person1.setName("Joe");
person1.setAge(30);
PersonBean person2 = new PersonBean();
person2.setName("Jane");
person2.setAge(25);
ArrayList arrayList1 = new ArrayList();
arrayList1.add(person1);
arrayList1.add(person2);
try {
System.out.println("List 'arrayList1' = '" + arrayList1 + "'");
FileOutputStream outputStream = new FileOutputStream("PersonBean.xml");
XMLEncoder encoder = new XMLEncoder(outputStream);
encoder.writeObject(arrayList1);
encoder.close();
Thread.sleep(10000);
} catch (Exception ex) {
}
try {
FileInputStream inputStream = new FileInputStream("PersonBean.xml");
XMLDecoder decoder = new XMLDecoder(inputStream);
ArrayList<PersonBean> arrayList2 = (ArrayList<PersonBean>) decoder.readObject();
decoder.close();
System.out.println("List 'arrayList2' = '" + arrayList2 + "'");
} catch (Exception ex) {
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.