- 什么是序列化?为什么在 Web Service 中需要它?
- Java Web Service 中主要的序列化技术:XML vs. JSON
- JAX-WS (Java API for XML Web Services) 中的 XML 序列化
- JAX-RS (Java API for RESTful Web Services) 中的 JSON/XML 序列化
- 常见问题与最佳实践
什么是序列化?为什么在 Web Service 中需要它?
序列化 的过程是将一个 Java 对象转换成一种可以存储或传输的格式(如字节流、XML、JSON 字符串等)。

反序列化 的过程则是将这种存储或传输的格式重新还原成原来的 Java 对象。
在 Web Service 中,序列化是必不可少的,因为:
- 跨平台/跨语言通信:Web Service 的核心思想是让不同技术栈(如 Java、.NET、Python)的应用程序能够相互通信,Java 对象不能直接在网络中传输,必须先转换成一种通用的、与语言无关的数据格式(如 XML 或 JSON),接收方再将其解析成自己语言中的对象。
- 网络传输:网络只能传输文本或二进制数据,对象是内存中的复杂结构,无法直接通过网络发送,序列化将其“打平”成数据流,才能通过网络传输。
Java Web Service 中主要的序列化技术:XML vs. JSON
在 Java Web Service 领域,主要有两种数据交换格式:
| 特性 | XML (eXtensible Markup Language) | JSON (JavaScript Object Notation) |
|---|---|---|
| 格式 | 标记语言,基于标签,如 <name>张三</name> |
键值对集合,如 {"name": "张三"} |
| 可读性 | 较好,但结构更冗长,标签多 | 非常好,结构简洁,易于人阅读和编写 |
| 解析性能 | 较慢,需要解析复杂的标签结构 | 非常快,解析器简单,直接映射到数据结构 |
| 数据体积 | 冗长,数据量大 | 紧凑,数据量小,网络传输效率高 |
| Schema 支持 | 强大的 XSD (XML Schema Definition) 支持 | 较新的 JSON Schema,也在不断完善 |
| 技术生态 | JAX-WS (SOAP) 的传统选择 | JAX-RS (REST) 的主流选择 |
- SOAP Web Service (基于 JAX-WS):通常强制使用 XML 作为数据交换格式。
- RESTful Web Service (基于 JAX-RS):更加灵活,可以同时支持 JSON 和 XML,但 JSON 因其简洁和高性能已成为事实上的标准。
JAX-WS (SOAP) 中的 XML 序列化
JAX-WS 是用于构建 SOAP Web Service 的标准 API,在 JAX-WS 中,序列化和反序列化通常是自动的,你只需要关注你的 Java Bean(POJO)即可。

核心概念:JAXB (Java Architecture for XML Binding)
JAX-WS 内部使用 JAXB 来处理 Java 对象和 XML 之间的转换,JAXB 2.0 (包含在 Java 6+ 中) 提供了注解驱动的绑定方式,非常方便。
示例:创建一个可序列化的 Java Bean
假设我们有一个 User 对象,需要通过网络传输。
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
// 1. 使用 @XmlRootElement 注解,表示这个类是 XML 文档的根元素
@XmlRootElement(name = "user")
public class User {
// 2. 使用 @XmlElement 注解,指定 Java 属性映射到 XML 元素的名称
// 如果不指定 name 属性,默认使用属性名
@XmlElement(name = "username")
private String name;
@XmlElement
private int age;
@XmlElement
private String email;
// 3. 必须提供一个无参构造函数,JAXB 在反序列化时需要它
public User() {
}
// 4. 可以提供一个有参构造函数方便创建对象
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// 5. 提供 getter 和 setter 方法,JAXB 通过它们来读写属性值
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", age=" + age + ", email='" + email + '\'' + '}';
}
}
当你把这个 User 对象作为 Web Service 方法的返回值时,JAX-WS 和 JAXB 会自动将其序列化为如下格式的 XML:
<user>
<username>张三</username>
<age>30</age>
<email>zhangsan@example.com</email>
</user>
客户端收到这个 XML 后,JAXB 也会自动将其反序列化回一个 User 对象。

JAXB 常用注解总结:
@XmlRootElement: 定义 XML 的根元素。@XmlElement: 定义一个属性对应的 XML 元素。@XmlAttribute: 将属性映射为 XML 的属性而不是元素。@XmlAccessorType: 控制哪些字段/属性需要被绑定,常用XmlAccessType.FIELD(直接绑定字段) 或XmlAccessType.PROPERTY(绑定 getter/setter)。@XmlTransient: 标记某个属性或字段,使其不参与序列化/反序列化。
JAX-RS (REST) 中的 JSON/XML 序列化
JAX-RS 是用于构建 RESTful Web Service 的标准 API,与 JAX-WS 不同,JAX-RS 的序列化框架是可插拔的,最流行的实现是 Jersey 和 RESTEasy。
默认情况下,JAX-RS 支持 XML 和 JSON,你通常需要引入相应的库。
示例:创建一个 REST 端点
我们还是用上面的 User 类,在 JAX-RS 中,这个类通常被称为 JAX-B Bean,因为它同样遵循 JAXB 的规范(注解相同)。
// User.java (与上面 JAX-WS 中的代码完全相同)
@XmlRootElement
public class User { ... }
我们创建一个 JAX-RS 资源类。
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces; // 指定可以生成的媒体类型
import javax.ws.rs.core.MediaType; // 媒体类型常量
@Path("/users")
public class UserResource {
@GET
@Path("/{userId}")
// 2. @Produces 注解声明该方法可以生成什么格式的响应
// 可以同时支持多种格式,客户端通过 "Accept" 请求头指定
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public getUserById() {
// 1. 创建一个 Java 对象
User user = new User("李四", 28, "lisi@example.com");
// 3. JAX-RS 运行时(如Jersey)会自动检测返回类型是 User,
// 并根据 @Produces 注解和客户端的 "Accept" 请求头,
// 自动调用底层 JSON/XML 库(如Jackson、JAXB)进行序列化。
return user;
}
}
如何支持 JSON?
你需要引入 JSON 处理库的依赖,以 Jersey 和 Jackson 为例:
Maven 依赖 (pom.xml):
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.39</version>
</dependency>
<!-- Jackson JSON 支持,Jersey 会自动检测并集成 -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.39</version>
</dependency>
当你访问这个 REST 端点时:
- 如果客户端请求头
Accept: application/json,响应会是:{ "username": "李四", "age": 28, "email": "lisi@example.com" } - 如果客户端请求头
