- JAX-WS (Java API for XML Web Services):这是 Java 官方标准,历史悠久,非常成熟,它通常用于创建基于 SOAP (Simple Object Access Protocol) 协议的 WebService,对于企业级应用,特别是需要强类型、安全性和事务支持的场景,JAX-WS 是首选。
- JAX-RS (Java API for RESTful Web Services):这是用于创建 RESTful Web 服务的 Java API,它基于 HTTP 协议,使用 JSON 或 XML 等格式传输数据,轻量级、简单易用,是目前 Web 开发(特别是前后端分离)的主流。
下面我将分别详细介绍如何使用这两种方式来编写 WebService。

使用 JAX-WS (SOAP WebService)
JAX-WS 是 Java EE 的一部分,因此如果你使用的是现代的 Jakarta EE (如 Jakarta EE 9+),那么包名会是 jakarta.ws.rs.*,这里我们以经典的 Java EE 8 / JAX-RS 2.1 为例,包名为 javax.ws.rs.*,因为它在社区中仍有广泛的应用。
准备工作
你需要一个 Java 开发环境(JDK)和一个构建工具(如 Maven),在 Maven 项目的 pom.xml 中添加依赖。
pom.xml 依赖:
<dependencies>
<!-- JAX-WS API -->
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- JAX-WS RI (Reference Implementation) - 用于开发和运行 -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
<!-- 为了方便启动内嵌服务器,我们使用 Jetty -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.48.v20250622</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.4.48.v20250622</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt-server</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
步骤 1: 创建 WebService 接口
定义一个 Java 接口,并使用 @WebService 注解来标记它,这个接口将作为我们 WebService 的契约。

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService: 将此接口声明为一个 WebService
// name: 服务名
// targetNamespace: 命名空间,通常是一个唯一的 URI
@WebService(
name = "UserService",
targetNamespace = "http://example.com/user"
)
// @SOAPBinding: 指定 SOAP 消息的风格
// STYLE.DOCUMENT: 表示 SOAP 消息体是文档风格的
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public interface UserWebService {
// @WebMethod: 将此方法暴露为 WebService 的一个操作
// @WebParam: 指定方法的参数名
@WebMethod
String sayHello(@WebParam(name = "name") String name);
@WebMethod
String getUserInfo(@WebParam(name = "userId") int userId);
}
步骤 2: 创建 WebService 的实现类
创建一个类来实现上面定义的接口。
import javax.jws.WebService;
// 注意:实现类上也要有 @WebService 注解
// endpointInterface: 指定实现的接口全限定名
@WebService(endpointInterface = "com.example.webservice.jaxws.UserWebService")
public class UserWebServiceImpl implements UserWebService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "!";
}
@Override
public String getUserInfo(int userId) {
// 模拟从数据库获取用户信息
if (userId == 1) {
return "User Info: ID=1, Name=John Doe, Email=john@example.com";
} else {
return "User not found with ID: " + userId;
}
}
}
步骤 3: 发布 WebService
我们需要将这个实现类发布到一个网络地址上,我们可以使用内嵌的 Jetty 服务器来发布。
import com.sun.xml.ws.transport.http.server.WSServerContainer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class JaxWsPublisher {
public static void main(String[] args) throws Exception {
// 创建一个 Jetty 服务器,监听 8080 端口
Server server = new Server(8080);
// 创建一个 Servlet 上下文处理器
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);
// 创建并添加 WSServlet
// 参数1: Servlet 的名字
// 参数2: WebService 实现类的实例
// 参数3: 发布的 URL 路径
ServletHolder holder = context.addServlet(WSServerContainer.class, "/ws");
holder.setInitParameter("javax.ws.rs.Application", "com.example.webservice.jaxws.JaxWsApplication");
// 启动服务器
server.start();
System.out.println("JAX-WS WebService started!");
System.out.println("WSDL is available at: http://localhost:8080/ws?wsdl");
server.join();
}
}
注意: 上述发布代码可能需要根据你使用的 JAX-WS RI 版本进行调整,更简单的方式是使用 Endpoint 类来发布。
使用 Endpoint 类发布 (更简单的方式):

import javax.xml.ws.Endpoint;
import javax.xml.ws.handler.HandlerResolver;
public class SimpleJaxWsPublisher {
public static void main(String[] args) {
// 创建 WebService 实例
UserWebService impl = new UserWebServiceImpl();
// 发布 WebService
// 参数1: 发布的 URL 地址
// 参数2: WebService 实现对象
Endpoint.publish("http://localhost:8080/ws", impl);
System.out.println("JAX-WS WebService published successfully!");
System.out.println("WSDL is available at: http://localhost:8080/ws?wsdl");
}
}
这种方式更简单,但通常需要一个外部的 Web 容器(如 Tomcat, Jetty)来运行,在开发阶段,直接使用 Endpoint.publish 非常方便。
如何测试?
- 查看 WSDL: 启动发布程序后,在浏览器中访问
http://localhost:8080/ws?wsdl,你应该能看到一个 XML 文件,这就是服务的描述语言。 - 使用客户端调用: 你可以使用 IDE(如 IntelliJ IDEA 或 Eclipse)的 "Generate Client" 功能,根据 WSDL 自动生成客户端代码,然后调用服务,也可以使用工具如 SoapUI 来测试。
使用 JAX-RS (RESTful WebService)
RESTful WebService 更加流行,因为它更符合现代 Web 应用的设计理念。
准备工作
在 Maven 项目的 pom.xml 中添加依赖,这里我们使用非常流行的 REST 框架 Jersey,它是 JAX-RS 的参考实现之一。
pom.xml 依赖:
<dependencies>
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.35</version>
</dependency>
<!-- JSON 支持 -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.35</version>
</dependency>
<!-- 为了方便启动内嵌服务器,我们使用 Grizzly -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>2.35</version>
</dependency>
</dependencies>
步骤 1: 创建资源类
在 REST 中,我们不再叫 "WebService",而是叫 "Resource"(资源),使用 @Path 注解来标记一个类为资源,并定义其 URL 路径,使用 @GET, @POST, @PUT, @DELETE 等注解来定义 HTTP 方法。
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
// @Path: 定义资源的根路径
@Path("users")
public class UserResource {
// @GET: 表示此方法处理 HTTP GET 请求
// @Path: 定义相对于类路径的子路径
// @Produces: 指定方法返回的媒体类型 (MIME type)
@GET
@Path("{userId}")
@Produces(MediaType.APPLICATION_JSON)
public UserInfo getUserInfo(@PathParam("userId") int userId) {
// 模拟从数据库获取用户信息
if (userId == 1) {
return new UserInfo(1, "John Doe", "john@example.com");
} else {
return null; // 或者抛出 404 Not Found 异常
}
}
// @GET: 处理另一个 GET 请求
@GET
@Path("greet")
@Produces(MediaType.TEXT_PLAIN)
public String sayHello(@QueryParam("name") String name) {
if (name == null || name.isEmpty()) {
return "Hello, Stranger!";
}
return "Hello, " + name + "!";
}
}
// 一个简单的 POJO (Plain Old Java Object),用于表示用户信息
class UserInfo {
private int id;
private String name;
private String email;
public UserInfo() {}
public UserInfo(int id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// Getters and Setters (非常重要,用于 JSON 序列化/反序列化)
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; }
}
步骤 2: 配置和启动应用
我们需要一个主类来引导和启动 Jersey 应用。
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 JaxRsPublisher {
// 定义基础 URI
public static final String BASE_URI = "http://localhost:8080/api/";
public static void main(String[] args) {
// 创建一个 ResourceConfig 实例,并注册我们的资源类
ResourceConfig config = new ResourceConfig();
config.packages("com.example.webservice.jaxrs"); // 扫描指定包下的所有资源类
// 创建并启动 Grizzly HTTP 服务器
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), config);
System.out.println("JAX-RS (Jersey) server started.");
System.out.println("WADL is available at: " + BASE_URI + "application.wadl");
System.out.println("Try accessing: " + BASE_URI + "users/1");
try {
server.start();
// 保持服务器运行
Thread.currentThread().join();
} catch (Exception e) {
e.printStackTrace();
}
}
}
如何测试?
- 启动服务器: 运行
JaxRsPublisher的main方法。 - 使用浏览器或 API 工具测试:
- 获取用户信息: 访问
http://localhost:8080/api/users/1,你应该会看到返回的 JSON 字符串:{"id":1,"name":"John Doe","email":"john@example.com"}。 - 调用问候语: 访问
http://localhost:8080/api/users/greet?name=Alice,你应该会看到:Hello, Alice!。 - 查看 WADL: 访问
http://localhost:8080/api/application.wadl,WADL 是 RESTful 服务的等价于 WSDL 的描述文件。
- 获取用户信息: 访问
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (REST) |
|---|---|---|
| 协议 | SOAP (基于 XML) | HTTP (GET, POST, PUT, DELETE) |
| 数据格式 | 主要是 XML | 主要是 JSON, 也可以是 XML, Text 等 |
| 风格 | 面向操作 | 面向资源 |
| 标准 | Java EE 标准 | Java EE 标准 |
| 复杂性 | 较高,有 WSDL、XSD 等 | 较低,更直观 |
| 安全性 | 内置 WS-Security 等标准 | 通常依赖 HTTPS 和 OAuth2 等标准 |
| 适用场景 | 企业应用集成 (EAI)、B2B 通信、需要强契约和事务的场景 | Web API、移动应用后端、前后端分离的 Web 应用 |
如何选择?
- 如果你的项目需要与传统的企业系统(如 .NET, SAP)集成,或者对安全性、事务有非常高的、标准化的要求,JAX-WS 是一个可靠的选择。
- 如果你在构建一个现代的、面向公众的 Web API,或者你的团队追求开发效率、轻量级和灵活性,JAX-RS 几乎是必然的选择,绝大多数新的 Java Web 服务项目都采用 RESTful 风格。
