将 Java 对象序列化为 XML – XMLEncoder
和XMLDecoder
示例
原文: https://howtodoinjava.com/java/serialization/xmlencoder-and-xmldecoder-example/
默认的 Java 序列化将 Java 对象转换为字节以通过网络发送。 但是很多时候,您将需要更多的跨平台媒体来发送此信息,例如 XML,以便使用不同技术的应用程序也可以利用此序列化信息的优势。 在此示例中,我们将学习将 Java 对象序列化为 XML 文件,然后反序列化回原始 Java 对象。
为了演示用法,我创建了一个具有 3 个字段的类UserSettings
,我们将序列化为 xml,然后将 xml 反序列化为 Java 对象。
public class UserSettings {
public UserSettings(){}
private Integer fieldOne;
private String fieldTwo;
private boolean fieldThree;
public Integer getFieldOne() {
return fieldOne;
}
public void setFieldOne(Integer fieldOne) {
this.fieldOne = fieldOne;
}
public String getFieldTwo() {
return fieldTwo;
}
public void setFieldTwo(String fieldTwo) {
this.fieldTwo = fieldTwo;
}
public boolean isFieldThree() {
return fieldThree;
}
public void setFieldThree(boolean fieldThree) {
this.fieldThree = fieldThree;
}
@Override
public String toString() {
return "UserSettings [fieldOne=" + fieldOne + ", fieldTwo=" + fieldTwo
+ ", fieldThree=" + fieldThree + "]";
}
}
使用XMLEncoder
从 Java 对象序列化为 XML 文件
首先来看XMLEncoder
类的示例,该类用于将 Java 对象序列化或编码为 XML 文件。
private static void serializeToXML (UserSettings settings) throws IOException
{
FileOutputStream fos = new FileOutputStream("settings.xml");
XMLEncoder encoder = new XMLEncoder(fos);
encoder.setExceptionListener(new ExceptionListener() {
public void exceptionThrown(Exception e) {
System.out.println("Exception! :"+e.toString());
}
});
encoder.writeObject(settings);
encoder.close();
fos.close();
}
XMLEncoder
使用反射来找出它们包含哪些字段,但不是以二进制形式编写这些字段,而是以 XML 编写。 待编码的对象不需要是可序列化的,但是它们确实需要遵循 Java Beans 规范,例如
- 该对象具有一个公共的空(无参数)构造器。
- 该对象具有每个受保护/私有财产的公共获取器和设置器。
运行以上代码将生成具有以下内容的 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_92" class="java.beans.XMLDecoder">
<object class="com.howtodoinjava.log4j2.examples.UserSettings">
<void property="fieldOne">
<int>10000</int>
</void>
<void property="fieldTwo">
<string>HowToDoInJava.com</string>
</void>
</object>
</java>
请注意,如果要写入的对象的属性的默认值未更改,则XmlEncoder
不会将其写出。 例如,在我们的示例中,第三个字段的类型为boolean
,其默认值为false
– 因此,它已从 XML 内容中省略。 这样可以灵活地更改类版本之间的默认值。
使用XMLDecoder
反序列化从 XML 到 Java 对象
现在,我们来看一下XMLDecoder
的示例,该示例已用于将 xml 文件反序列化为 java 对象。
private static UserSettings deserializeFromXML() throws IOException {
FileInputStream fis = new FileInputStream("settings.xml");
XMLDecoder decoder = new XMLDecoder(fis);
UserSettings decodedSettings = (UserSettings) decoder.readObject();
decoder.close();
fis.close();
return decodedSettings;
}
XMLEncoder
和XMLDecoder
比序列化框架宽容得多。 解码时,如果属性更改了类型,或者属性被删除/添加/移动/重命名,则解码将“尽其所能”进行解码,同时跳过无法解码的属性。
完整的例子
让我们看一下使用XMLEncoder
和XMLDecoder
的整个示例。
import java.beans.ExceptionListener;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class XMLEncoderDecoderExample
{
public static void main(String[] args) throws IOException
{
UserSettings settings = new UserSettings();
settings.setFieldOne(10000);
settings.setFieldTwo("HowToDoInJava.com");
settings.setFieldThree(false);
//Before
System.out.println(settings);
serializeToXML ( settings );
UserSettings loadedSettings = deserializeFromXML();
//After
System.out.println(loadedSettings);
}
private static void serializeToXML (UserSettings settings) throws IOException
{
FileOutputStream fos = new FileOutputStream("settings.xml");
XMLEncoder encoder = new XMLEncoder(fos);
encoder.setExceptionListener(new ExceptionListener() {
public void exceptionThrown(Exception e) {
System.out.println("Exception! :"+e.toString());
}
});
encoder.writeObject(settings);
encoder.close();
fos.close();
}
private static UserSettings deserializeFromXML() throws IOException {
FileInputStream fis = new FileInputStream("settings.xml");
XMLDecoder decoder = new XMLDecoder(fis);
UserSettings decodedSettings = (UserSettings) decoder.readObject();
decoder.close();
fis.close();
return decodedSettings;
}
}
Output:
UserSettings [fieldOne=10000, fieldTwo=HowToDoInJava.com, fieldThree=false]
UserSettings [fieldOne=10000, fieldTwo=HowToDoInJava.com, fieldThree=false]
将我的问题放在评论部分。
学习愉快!