java中用于序列化的XMLEncoder
我只是想知道如何序列化java中用于序列化的XMLEncoder,java,serialization,Java,Serialization,我只是想知道如何序列化ArrayList,其中foo是我自己创建的类 我是否需要做一些特别的事情,比如首先定义自己的xml结构,然后调用列表中每个值的toString并写出它 有人能给我指一本好的教程吗?这就是我一直在看的,但它似乎没有提到如何处理非图书馆类 谢谢如果您正在寻找XML序列化,我建议您选择 使用XMLEncoder序列化ArrayList没有什么特别之处 以下是一个例子: 有一个bean类TestBean: public class TestBean { private St
ArrayList
,其中foo是我自己创建的类
我是否需要做一些特别的事情,比如首先定义自己的xml结构,然后调用列表中每个值的toString并写出它
有人能给我指一本好的教程吗?这就是我一直在看的,但它似乎没有提到如何处理非图书馆类
谢谢如果您正在寻找XML序列化,我建议您选择
使用XMLEncoder序列化ArrayList没有什么特别之处 以下是一个例子: 有一个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);
}
}
还有一个类Main,它序列化了一个ArrayList
,并再次读取它:
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();
}
}
}
TestBean
中的toString()
方法仅用于漂亮的打印。它不会影响XML序列化。XMLEncoder可以用于任何类,包括用户定义的类-您提到的文章确实详细介绍了如何实现这一点,但它写得不是很好,因此可能有点难以理解
如果用户定义的类遵循,则可以使用encoder.writeObject()
序列化列表
实例。这是因为XML输出只是关于如何在运行时重新创建给定实例的一系列指令。默认的PersistenceDelegate知道如何序列化列表结构,但只有未知类的默认行为。默认情况下,它试图通过调用其空(无参数)构造函数来重新创建给定的对象实例,然后将其属性逐个设置为给定实例的值——如果该类是JavaBean,这一点保证是可能的
如果类的某些属性是只读的,即它们是由构造函数设置的,并且在构建后无法更改,那么您必须(稍微)做更多的工作才能使其正常工作。您可以创建DefaultPersistenceDelegate的自定义实例,该实例可以识别您的类,并知道如何将适当的数据传递给其构造函数—您只需将属性名称作为列表传递给它,其余的工作将由它完成:
PersistenceDelegate fooDelegate = new DefaultPersistenceDelegate(new String[] {"propertyName1", "propertyName2"});
encoder.setPersistenceDelegate(Foo.class, fooDelegate);
如果类的构造函数参数不能直接映射到使用getter方法的属性,和/或恢复对象状态还有其他复杂性,通常可以通过扩展PersistenceDelegate并自己实现必要的行为来解决这些问题。但是,如果你的类在运行时很难重新创建,你希望它被序列化,你应该认真考虑重新设计它来减少它的复杂性——这将使整个过程变得更容易,并且将大大减少错误的机会。我不知道为什么互联网上有这么多的例子是不完整的或者不起作用的,而这些例子只需要稍加注意就可以变得更有用。下面是一个完整的示例,它可以在一个文件(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) {
}
}
}
//此示例创建两个PersonBean,创建一个ArrayList,将这些Bean添加到
//列表,将ArrayList序列化为XML文件。
//然后它从XML文件加载到一个新的ArrayList中
//
//关键词:ArrayList、序列化、XMLEncode、XMLDecode
//注意:在10秒Thread.sleep等待查看时更改XML文件
//数据实际上是从文件中加载的。
导入java.io.FileOutputStream;
导入java.io.FileInputStream;
导入java.beans.xmlcoder;
导入java.beans.xml解码器;
导入java.util.ArrayList;
公共类PersonBean{
私有字符串名称;
私人互联网;
公共字符串getName(){
返回名称;
}
public int getAge(){
回归年龄;
}
公共无效集合名(字符串名){
this.name=名称;
}
公共无效设置(整数){
这个。年龄=年龄;
}
@凌驾
公共字符串toString(){
返回String.format(“[PersonBean:name='%s',age=%d]”,name,age);
}
公共静态void main(字符串[]args){
PersonBean person1=新的PersonBean();
人员1.设置名称(“乔”);
人1.体位(30);
PersonBean person2=新PersonBean();
人2.集名(“简”);
人物2.背景(25);
ArrayList ArrayList 1=新的ArrayList();
arrayList1.add(person1);
arrayList1.add(person2);
试一试{
System.out.println(“List'arrayList1'='”+arrayList1+“”);
FileOutputStream outputStream=新的FileOutputStream(“PersonBean.xml”);
XMLEncoder编码器=新的XMLEncoder(outputStream);
encoder.writeObject(arrayList1);
encoder.close();
睡眠(10000);
}捕获(例外情况除外){
}
试一试{
FileInputStream inputStream=新的FileInputStream(“PersonBean.xml”);
XMLDecoder decoder=新的XMLDecoder(inputStream);
ArrayList ArrayList 2=(ArrayList)解码器。readObject();
close();
System.out.println(“List'arrayList2'='”+arrayList2+“”);
}捕获(例外情况除外){
}
}
}
我发现这不管用,xstream示例非常管用,但究竟什么不管用?我从工作示例代码中提取了这个。您是否在TestBean中实现了getter和setter?我只为此插入了一条适当的注释。此实现适用于按照JavaBeans约定编码的类,但对于任意用户定义的类,有必要确保XMLEncoder具有正确的PersistenceDelegate。不是所有的类都有属性,也不是所有的属性都是可写的——你的类离JavaBeans约定越远,你就需要付出更多的努力。
PersistenceDelegate fooDelegate = new DefaultPersistenceDelegate(new String[] {"propertyName1", "propertyName2"});
encoder.setPersistenceDelegate(Foo.class, fooDelegate);
// 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) {
}
}
}