将 Java 对象序列化为 XML – XMLEncoder和XMLDecoder示例

将 Java 对象序列化为 XML – XMLEncoderXMLDecoder示例

原文: 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 规范,例如

  1. 该对象具有一个公共的空(无参数)构造器。
  2. 该对象具有每个受保护/私有财产的公共获取器和设置器。

运行以上代码将生成具有以下内容的 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;
}

XMLEncoderXMLDecoder比序列化框架宽容得多。 解码时,如果属性更改了类型,或者属性被删除/添加/移动/重命名,则解码将“尽其所能”进行解码,同时跳过无法解码的属性。

完整的例子

让我们看一下使用XMLEncoderXMLDecoder的整个示例。

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]

将我的问题放在评论部分。

学习愉快!