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

> 原文： [https://howtodoinjava.com/java/serialization/xmlencoder-and-xmldecoder-example/](https://howtodoinjava.com/java/serialization/xmlencoder-and-xmldecoder-example/)

默认的 Java 序列化将 Java 对象转换为字节以通过网络发送。 但是很多时候，您将需要更多的跨平台媒体来发送此信息，例如 XML，以便使用不同技术的应用程序也可以利用此序列化信息的优势。 在此示例中，我们将学习将 Java 对象序列化为 XML 文件，然后反序列化回原始 Java 对象。

为了演示用法，我创建了一个具有 3 个字段的类`UserSettings`，我们将**序列化为 xml**，然后**将 xml 反序列化为 Java 对象**。

```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`](https://docs.oracle.com/javase/8/docs/api/java/beans/XMLEncoder.html)类的示例，该类用于将 Java 对象序列化或编码为 XML 文件。

```java
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 编写。 待编码的对象不需要是[可序列化的](//howtodoinjava.com/java/serialization/a-mini-guide-for-implementing-serializable-interface-in-java/)，但是它们确实需要遵循 [Java Beans 规范](https://docs.oracle.com/javase/tutorial/javabeans/writing/index.html)，例如

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

运行以上代码将生成具有以下内容的 XML 文件：

```java
<?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`](https://docs.oracle.com/javase/8/docs/api/java/beans/XMLDecoder.html)的示例，该示例已用于将 xml 文件反序列化为 java 对象。

```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`的整个示例。

```java
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;
    }
}

```

```java
Output:

UserSettings [fieldOne=10000, fieldTwo=HowToDoInJava.com, fieldThree=false]
UserSettings [fieldOne=10000, fieldTwo=HowToDoInJava.com, fieldThree=false]
```

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

学习愉快！