- JAX-WS (Java API for XML Web Services):这是 Java 官方、成熟的 WebService 标准,它非常稳定,与 Java EE (Jakarta EE) 深度集成,特别适合构建传统的、基于 SOAP 协议的 WebService,对于新项目,如果必须使用 SOAP,JAX-WS 是首选。
- JAX-RS (Java API for RESTful Web Services):这是用于构建 RESTful 风格 Web 服务的标准,RESTful 服务通常使用 HTTP 协议,以 JSON 或 XML 作为数据格式,轻量、简单、易于与前端(特别是 JavaScript)集成,绝大多数新的 Web 服务都采用 RESTful 风格。
下面我将分别介绍如何使用这两种技术来创建 WebService。

准备工作:开发环境
- JDK: Java Development Kit (版本 8 或更高版本)。
- 构建工具: Maven 或 Gradle,这里我们以 Maven 为例,因为它非常普及且配置简单。
- IDE: IntelliJ IDEA 或 Eclipse。
使用 JAX-WS (SOAP WebService)
JAX-WS 的核心思想是:通过一个 Java 接口来定义服务的契约(WSDL),然后由 JDK 或框架(如 Apache CXF)帮你自动实现这个接口并发布成 WebService。
步骤 1:创建 Maven 项目
在 IDE 中创建一个新的 Maven 项目,pom.xml 文件基本可以保持为默认的 maven-archetype-quickstart。
步骤 2:编写服务接口和实现类
这是 JAX-WS 的核心,你需要定义一个 Java 接口,并用 @WebService 注解来标记它。
服务接口 (src/main/java/com/example/HelloService.java)

package com.example;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* 使用 @WebService 注解标记这是一个 WebService 接口
* name: 服务名
* targetNamespace: 命名空间,通常使用反向域名
*/
@WebService(name = "HelloService", targetNamespace = "http://example.com/")
public interface HelloService {
/**
* 使用 @WebMethod 注解标记这是一个 WebService 方法
* operationName: 方法的公开名称
*/
@WebMethod(operationName = "sayHello")
String sayHello(@WebParam(name = "name") String name);
}
服务实现类 (src/main/java/com/example/HelloServiceImpl.java)
package com.example;
import javax.jws.WebService;
/**
* 使用 @WebService 注解实现接口
* endpointInterface: 指明实现的是哪个接口
*/
@WebService(endpointInterface = "com.example.HelloService")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "你好, " + name + "! 欢迎使用 JAX-WS WebService.";
}
}
步骤 3:发布 WebService
我们可以使用 JDK 内置的 Endpoint 类来快速发布服务,这非常适合开发和测试。
创建发布类 (src/main/java/com/example/WebServicePublisher.java)
package com.example;
import javax.xml.ws.Endpoint;
/**
* WebService 发布器
*/
public class WebServicePublisher {
public static void main(String[] args) {
// 定义服务的访问地址
String address = "http://localhost:8888/ws/hello";
// 发布服务
// 参数1: 服务的访问地址
// 参数2: 服务的实现类实例
Endpoint.publish(address, new HelloServiceImpl());
System.out.println("WebService 发布成功!");
System.out.println("访问地址: " + address + "?wsdl");
System.out.println("你可以使用浏览器或 SOAP UI 工具访问这个地址来查看 WSDL 文档。");
}
}
步骤 4:运行和测试
-
运行:直接运行
WebServicePublisher的main方法。
(图片来源网络,侵删) -
验证 WSDL:打开浏览器,访问
http://localhost:8888/ws/hello?wsdl,如果看到一个 XML 文件(WSDL 定义),说明服务发布成功。 -
客户端测试:
-
使用 JDK 自带的
wsimport工具:# 在命令行中执行,根据你的 WSDL 地址生成客户端代码 wsimport -keep -p com.example.client http://localhost:8888/ws/hello?wsdl
这会在
com.example.client包下生成一堆 Java 文件(接口、实现类等),然后你可以写一个简单的客户端来调用。 -
使用 SOAP UI:这是一个专业的 SOAP 测试工具,创建一个新的 SOAP Project,输入 WSDL 地址,它会自动解析出所有可用的方法,你可以直接填写参数并发送请求来测试。
-
使用 JAX-RS (RESTful WebService)
JAX-RS 是一个标准,不同的实现(框架)提供了不同的功能,最流行、功能最强大的实现是 Jersey 和 RESTEasy,这里我们以 Jersey 为例,因为它是 JAX-RS 的参考实现。
步骤 1:创建 Maven 项目
创建一个新的 Maven 项目,并在 pom.xml 中添加 Jersey 的依赖。
pom.xml
<dependencies>
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<!-- 使用 2.35 版本,与 Jakarta EE 9+ 兼容 -->
<version>2.35</version>
</dependency>
<!-- 支持 JSON 格式 (需要 Jackson) -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.35</version>
</dependency>
</dependencies>
步骤 2:编写资源类
在 RESTful 架构中,每个 URL 路径都对应一个“资源”,资源由一个 Java 类(Resource Class)来表示,类中的公共方法就是处理 HTTP 请求的“方法”。
资源类 (src/main/java/com/example/Resource.java)
package com.example;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* @Path: 定义资源的基本路径
* @Produces: 定义该方法能产生的媒体类型,这里是 JSON
* @Consumes: 定义该方法能接受的媒体类型,这里是 JSON
*/
@Path("users")
public class Resource {
// GET 请求: http://localhost:8080/api/users/123
@GET
@Path("/{userId}")
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam("userId") int userId) {
System.out.println("收到 GET 请求,用户ID: " + userId);
// 模拟从数据库获取用户
User user = new User();
user.setId(userId);
user.setName("张三");
user.setEmail("zhangsan@example.com");
return user;
}
// POST 请求: http://localhost:8080/api/users
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
System.out.println("收到 POST 请求,新用户: " + user.getName());
// 模拟将用户保存到数据库
// ... save logic ...
// 返回一个 201 Created 响应,并包含新创建资源的路径
return Response.status(Response.Status.CREATED)
.entity("用户创建成功,ID: " + user.getId())
.build();
}
}
// 一个简单的 POJO (Plain Old Java Object),用于表示数据
class User {
private int id;
private String name;
private String email;
// 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; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
步骤 3:配置和启动 HTTP 服务器
Jersey 本身不包含 HTTP 服务器,所以我们需要一个像 Grizzly 或 Jetty 这样的服务器来托管我们的应用。
启动类 (src/main/java/com/example/Main.java)
package com.example;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import java.io.IOException;
import java.net.URI;
/**
* Jersey 服务器启动类
*/
public class Main {
// 定义基础 URI
public static final String BASE_URI = "http://localhost:8080/api/";
public static void main(String[] args) {
// 1. 创建一个 ResourceConfig 实例,并注册我们的资源类
// 扫描 com.example 包下的所有资源
final ResourceConfig rc = new ResourceConfig().packages("com.example");
// 2. 创建 Grizzly HTTP 服务器
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
try {
// 3. 启动服务器
System.out.println("Jersey 应用启动,访问地址: " + BASE_URI);
server.start();
// 保持服务器运行
Thread.currentThread().join();
} catch (IOException | InterruptedException e) {
System.err.println("服务器启动失败: " + e.getMessage());
}
}
}
步骤 4:运行和测试
- 运行:直接运行
Main类的main方法。 - 测试:
- 浏览器测试:
- GET 请求:在浏览器地址栏输入
http://localhost:8080/api/users/123,浏览器会显示一个 JSON 字符串:{"id":123,"name":"张三","email":"zhangsan@example.com"}。
- GET 请求:在浏览器地址栏输入
- 命令行工具测试 (使用
curl):- GET 请求:
curl http://localhost:8080/api/users/123
- POST 请求 (需要发送 JSON 数据):
curl -X POST -H "Content-Type: application/json" -d '{"id":0,"name":"李四","email":"lisi@example.com"}' http://localhost:8080/api/users你会看到服务器返回
用户创建成功,ID: 0。
- GET 请求:
- 浏览器测试:
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (RESTful) |
|---|---|---|
| 协议 | SOAP (Simple Object Access Protocol) | HTTP (GET, POST, PUT, DELETE 等) |
| 数据格式 | XML (默认),也支持 JSON | JSON (主流),也支持 XML |
| 架构风格 | 面向服务,有严格的契约 (WSDL) | 面向资源,无状态 |
| 优点 | - 标准化,跨语言能力强 - 内置安全、事务等机制 - 契约驱动,易于集成 |
- 轻量,简单,性能好 - 无需 XML 解析,直接使用 HTTP - 非常适合前后端分离的 Web 应用 |
| 缺点 | - 协议复杂,笨重 - 学习曲线稍陡 - 不适合浏览器直接调用 |
- 无统一标准,实现方式多样 - 安全性需要自己实现 |
| 适用场景 | - 企业级应用集成 (B2B) - 需要强类型和严格契约的系统 - 金融、电信等传统行业 |
- 移动应用后端 API - 现代化的 Web 应用 (前后端分离) - 微服务架构 |
如何选择?
- 如果你的项目需要与传统的、基于 SOAP 的企业系统(如 .NET 服务)集成,或者你需要一个强契约、高安全性的服务,选择 JAX-WS。
- 如果你在构建一个新的 Web 应用,特别是需要为移动端或前端提供 API,或者你倾向于轻量级、易于开发和维护的架构,强烈推荐选择 JAX-RS (RESTful),RESTful 已经成为 Web 服务开发的主流。
