杰瑞科技汇

Java webservice 序列化如何实现与优化?

  1. 什么是序列化?为什么在 Web Service 中需要它?
  2. Java Web Service 中主要的序列化技术:XML vs. JSON
  3. JAX-WS (Java API for XML Web Services) 中的 XML 序列化
  4. JAX-RS (Java API for RESTful Web Services) 中的 JSON/XML 序列化
  5. 常见问题与最佳实践

什么是序列化?为什么在 Web Service 中需要它?

序列化 的过程是将一个 Java 对象转换成一种可以存储或传输的格式(如字节流、XML、JSON 字符串等)。

Java webservice 序列化如何实现与优化?-图1
(图片来源网络,侵删)

反序列化 的过程则是将这种存储或传输的格式重新还原成原来的 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):更加灵活,可以同时支持 JSONXML,但 JSON 因其简洁和高性能已成为事实上的标准。

JAX-WS (SOAP) 中的 XML 序列化

JAX-WS 是用于构建 SOAP Web Service 的标准 API,在 JAX-WS 中,序列化和反序列化通常是自动的,你只需要关注你的 Java Bean(POJO)即可。

Java webservice 序列化如何实现与优化?-图2
(图片来源网络,侵删)

核心概念: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 对象。

Java webservice 序列化如何实现与优化?-图3
(图片来源网络,侵删)

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 的序列化框架是可插拔的,最流行的实现是 JerseyRESTEasy

默认情况下,JAX-RS 支持 XMLJSON,你通常需要引入相应的库。

示例:创建一个 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 处理库的依赖,以 JerseyJackson 为例:

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"
    }
  • 如果客户端请求头
分享:
扫描分享到社交APP
上一篇
下一篇