- JAX-WS (Java API for XML Web Services):这是 Java 官方、标准的 WebService 技术,非常成熟、稳定,广泛应用于企业级开发,它默认使用 SOAP 协议。
- JAX-RS (Java API for RESTful Web Services):这是创建 RESTful Web 服务的标准 API,它使用 HTTP 协议,通常以 JSON 或 XML 格式传输数据,是目前 Web 开发(特别是前后端分离架构)的主流选择。
下面我将分别详细介绍如何使用这两种技术来创建 WebService。

准备工作:开发环境
你需要一个 Java 开发环境(如 JDK 8 或更高版本)和一个构建工具(如 Maven 或 Gradle),这里我们以 Maven 为例。
使用 JAX-WS (SOAP WebService)
JAX-WS 是 Java EE 的一部分,现在也包含在 Jakarta EE 中,我们不需要引入太多额外的依赖,因为它们通常已经包含在 JDK 或应用服务器(如 Tomcat, JBoss, WebLogic)中。
创建 Maven 项目
在 IDE(如 IntelliJ IDEA 或 Eclipse)中创建一个新的 Maven 项目。
添加 Maven 依赖
虽然 JAX-WS 核心 API 在 JDK 中,但为了方便地开发、测试和发布服务,我们可以使用 javax.xml.ws:jaxws-api 和 com.sun.xml.ws:jaxws-rt (这是参考实现,用于本地开发和测试)。

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jax-ws-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- JAX-WS API -->
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- JAX-WS Reference Implementation (for local development and testing) -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 使用 Maven 插件来编译 JAX-WS 注解 -->
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
创建 WebService 接口和实现
定义一个服务接口,并用 @WebService 注解标记它。
HelloService.java (接口)
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HelloService {
@WebMethod
String sayHello(@WebParam(name = "name") String name);
@WebMethod
int getAge(@WebParam(name = "name") String name);
}
创建这个接口的实现类。
HelloServiceImpl.java (实现)

import javax.jws.WebService;
@WebService(endpointInterface = "com.example.HelloService") // 指定实现的接口
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "!";
}
@Override
public int getAge(String name) {
// 模拟逻辑
if ("Alice".equals(name)) {
return 30;
}
return -1; // 表示未知
}
}
发布 WebService
创建一个主类来发布这个服务,我们将它发布在 http://localhost:8080/hello 这个地址上。
Publisher.java
import javax.xml.ws.Endpoint;
public class Publisher {
public static void main(String[] args) {
// 创建服务的实现实例
HelloService helloService = new HelloServiceImpl();
// 发布服务
// 第一个参数是服务的访问地址(Endpoint URL)
// 第二个参数是服务的实现对象
String address = "http://localhost:8080/hello";
Endpoint.publish(address, helloService);
System.out.println("WebService is published at: " + address);
}
}
运行和测试
- 运行
Publisher.java,你会看到控制台输出 "WebService is published at: http://localhost:8080/hello"。 - 打开浏览器,访问
http://localhost:8080/hello?wsdl。如果看到一个 XML 文件(WSDL 文件),恭喜你,服务发布成功了!WSDL 是 WebService 的描述语言,定义了服务的接口、地址、协议等信息。
- 使用客户端测试,你可以使用 IDE 的 WebService 客户端功能,或者使用
wsimport命令生成客户端代码进行测试。
使用 JAX-RS (RESTful WebService)
JAX-RS 的参考实现是 Jersey,另一个流行的实现是 RESTEasy,这里我们以 Jersey 为例。
创建 Maven 项目
创建一个新的 Maven 项目。
添加 Maven 依赖
我们需要添加 Jersey 的核心依赖以及一个运行它的服务器(如 Grizzly 或嵌入式 Jetty),这里我们使用 Grizzly。
<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jax-rs-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jersey.version>2.39.1</jersey.version>
</properties>
<dependencies>
<!-- Jersey Core -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- JSON Support -->
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>${jersey.version}</version>
</dependency>
</dependencies>
</project>
创建资源类
在 JAX-RS 中,服务被定义为“资源”(Resource),我们创建一个 POJO(普通的 Java 对象)并用 Jersey 的注解来标记它。
UserResource.java
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
// @Path 定义了资源的 URI 路径
@Path("/users")
public class UserResource {
// 模拟一个数据库
private List<User> users = new ArrayList<>();
public UserResource() {
users.add(new User(1, "Alice"));
users.add(new User(2, "Bob"));
}
// @GET 表示这是一个处理 GET 请求的方法
// @Path("all") 定义了子路径
// @Produces 定义了返回的媒体类型
@GET
@Path("/all")
@Produces(MediaType.APPLICATION_JSON)
public List<User> getAllUsers() {
return users;
}
// @Path("{id}") 是一个路径参数
// @PathParam("id") 用于获取路径中的值
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserById(@PathParam("id") int id) {
User user = users.stream()
.filter(u -> u.getId() == id)
.findFirst()
.orElse(null);
if (user == null) {
// 返回 404 Not Found
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
// 返回 200 OK 和用户对象
return Response.ok(user).build();
}
// @POST 表示处理 POST 请求
// @Consumes 定义了接受的媒体类型
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
// 模拟创建用户
user.setId(users.size() + 1);
users.add(user);
// 返回 201 Created 和新创建的用户
return Response.status(Response.Status.CREATED).entity(user).build();
}
// @PUT 表示处理 PUT 请求
@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateUser(@PathParam("id") int id, User updatedUser) {
for (User user : users) {
if (user.getId() == id) {
user.setName(updatedUser.getName());
return Response.ok(user).build();
}
}
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
// @DELETE 表示处理 DELETE 请求
@DELETE
@Path("{id}")
public Response deleteUser(@PathParam("id") int id) {
boolean removed = users.removeIf(u -> u.getId() == id);
if (removed) {
return Response.noContent().build(); // 204 No Content
}
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
}
// 一个简单的 POJO,用于表示用户
class User {
private int id;
private String name;
public User() {}
public User(int id, String name) {
this.id = id;
this.name = name;
}
// Getters and Setters
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
启动服务器
创建一个主类来启动 Grizzly 服务器并注册我们的资源。
Main.java
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import java.net.URI;
public class Main {
// 定义服务的基地 URI
public static final String BASE_URI = "http://localhost:8080/api/";
public static void main(String[] args) {
// 创建一个 ResourceConfig 实例,并注册我们的资源类
ResourceConfig rc = new ResourceConfig().packages("com.example");
// 创建并启动 Grizzly HTTP 服务器
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
System.out.println("Jersey app started at " + BASE_URI);
System.out("Hit enter to stop it...");
try {
System.in.read();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.shutdownNow();
}
}
}
运行和测试
-
运行
Main.java,你会看到控制台输出 Jersey 服务已启动。 -
使用 API 工具(如 Postman, Insomnia)或浏览器进行测试。
-
获取所有用户:
- 方法:
GET - URL:
http://localhost:8080/api/users/all - 预期响应:
[{ "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }]
- 方法:
-
根据 ID 获取用户:
- 方法:
GET - URL:
http://localhost:8080/api/users/1 - 预期响应:
{ "id": 1, "name": "Alice" }
- 方法:
-
创建新用户:
- 方法:
POST - URL:
http://localhost:8080/api/users - Body (raw, JSON):
{ "name": "Charlie" } - 预期响应 (Status 201):
{ "id": 3, "name": "Charlie" }
- 方法:
-
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (REST) |
|---|---|---|
| 协议 | SOAP (Simple Object Access Protocol) | HTTP (GET, POST, PUT, DELETE 等) |
| 数据格式 | 默认 XML,也可配置其他格式 | 默认 JSON,也可配置 XML 等 |
| 地址风格 | 基于动作,通常只有一个地址 | 基于资源,清晰的 URI 结构 |
| 标准 | Java EE / Jakarta EE 标准 | Java EE / Jakarta EE 标准 |
| 优点 | - 标准化程度高 - 内置安全、事务支持 - 自动生成客户端代理 |
- 轻量、简单 - 无状态,适合互联网应用 - 更好的缓存和可扩展性 - 与前端框架(如 React, Vue)完美集成 |
| 缺点 | - 协议复杂,冗余 - 调试困难 - 学习曲线较陡 |
- 功能相对简单 - 安全、事务需自行实现 |
| 适用场景 | - 企业内部系统(如 ERP, CRM 集成) - 对安全性、事务性要求高的场景 |
- 公开 API - 移动应用后端 - 前后端分离的 Web 应用 |
如何选择?
- 如果你需要与传统的、基于 SOAP 的企业系统(如 .NET, SAP)集成,或者你的项目对事务和安全有极高的标准化要求,选择 JAX-WS。
- 如果你正在构建一个现代化的 Web 应用或 API,特别是需要支持多种客户端(Web, Mobile, 前端框架),并且追求轻量、简单和高效,JAX-RS 是不二之选,JAX-RS 是更主流、更受欢迎的选择。
