- JAX-WS (Java API for XML Web Services):这是 Java 官方、标准的 WebService 实现方式,基于 SOAP 协议,它非常成熟,稳定,并且被广泛用于企业级应用中,Java 6 及以上版本已经内置了 JAX-WS 的实现(参考实现是 Metro)。
- JAX-RS (Java API for RESTful Web Services):这是用于实现 RESTful 风格 Web 服务的 API,它更轻量级,通常基于 HTTP 协议,使用 JSON 或 XML 作为数据格式,非常适合移动应用和前后端分离的架构,其最流行的实现是 Jersey 和 RESTEasy。
下面我将分别详细介绍这两种方式的实现步骤。

使用 JAX-WS (SOAP)
JAX-WS 的核心思想是,你只需要编写一个普通的 Java 接口和它的实现类,然后通过工具生成 WSDL (Web Services Description Language) 文件,客户端通过这个 WSDL 文件来了解如何调用你的服务。
创建服务端
步骤 1:创建服务接口
这是一个普通的 Java 接口,用 @WebService 注解来标记它。
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 指定这是一个 WebService 接口
@WebService
// @SOAPBinding.Style.RPC 表示使用 RPC 风格,这是默认的
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWorldService {
// @WebMethod 指定这是一个对外暴露的方法
@WebMethod
String sayHello(String name);
}
步骤 2:创建服务实现类

这个类实现了上面的接口。
import javax.jws.WebService;
// @WebService(endpointInterface = "com.example.HelloWorldService")
// 指定实现的接口,这是最佳实践
@WebService(endpointInterface = "com.example.jaxws.HelloWorldService")
public class HelloWorldServiceImpl implements HelloWorldService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "!";
}
}
步骤 3:发布服务
你可以通过一个简单的 Java main 方法来发布这个服务,服务会发布在指定的 URL 上。
import javax.xml.ws.Endpoint;
public class HelloWorldPublisher {
public static void main(String[] args) {
// 定义服务的发布地址
String address = "http://localhost:8888/ws/hello";
// 创建服务实现类的实例
HelloWorldService helloWorldService = new HelloWorldServiceImpl();
// 发布服务
Endpoint.publish(address, helloWorldService);
System.out.println("WebService is published at: " + address);
}
}
步骤 4:测试服务
- 运行
HelloWorldPublisher的main方法。 - 打开浏览器,访问
http://localhost:8888/ws/hello?wsdl。 - 如果看到一堆 XML 代码(这就是 WSDL 文件),说明服务发布成功。
如何生成客户端?
你可以使用 JDK 自带的 wsimport 工具来生成客户端代码。
打开命令行,执行以下命令:
wsimport -keep -p com.example.jaxws.client http://localhost:8888/ws/hello?wsdl
-keep: 生成源代码。-p: 指定生成的包名。- 后面是 WSDL 文件的 URL。
执行后,会在 com.example.jaxws.client 包下生成一堆 Java 文件(包括接口、实现类、辅助类等)。
使用生成的客户端:
public class HelloWorldClient {
public static void main(String[] args) {
// 创建服务实例,通过生成的 Service 类
HelloWorldService_Service service = new HelloWorldService_Service();
// 获取服务端口,通过生成的 HelloWorldService 接口
HelloWorldService helloService = service.getHelloWorldServicePort();
// 调用远程方法
String response = helloService.sayHello("World");
System.out.println("Response from WebService: " + response);
}
}
使用 JAX-RS (RESTful REST)
这种方式更现代,更灵活,是目前 Web 开发的主流,我们以 Jersey 作为实现框架为例。
准备环境
你需要添加 Jersey 的依赖,如果你使用 Maven,在 pom.xml 中添加:
<dependencies>
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.39</version> <!-- 使用最新稳定版本 -->
</dependency>
<!-- 支持 JSON 的依赖 -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.39</version>
</dependency>
</dependencies>
创建服务端
步骤 1:创建资源类
这个类相当于 MVC 中的 Controller,用 @Path 注解定义 URI 路径,用 @GET, @POST 等注解定义 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 定义了这个资源的 URI 路径
@Path("/greeting")
public class GreetingResource {
// @GET 表示这个方法处理 HTTP GET 请求
// @Path("hello") 定义了更具体的子路径
// @Produces("text/plain") 指定返回的媒体类型是纯文本
@GET
@Path("hello")
@Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
return "Hello, Jersey!";
}
// 路径中可以包含参数
@GET
@Path("hello/{name}")
@Produces(MediaType.TEXT_PLAIN)
public String sayHelloToSomeone(@PathParam("name") String name) {
return "Hello, " + name + "!";
}
}
步骤 2:配置并部署到 Web 容器 (如 Tomcat)
RESTful 服务不能像 JAX-WS 那样用一个 main 方法发布,通常需要部署到一个 Servlet 容器(如 Tomcat, Jetty)中。
-
创建一个配置类:这个类用于注册你的资源。
import org.glassfish.jersey.server.ResourceConfig; import javax.ws.rs.ApplicationPath; // @ApplicationPath 定义了所有资源的根路径 @ApplicationPath("/api") public class JerseyConfig extends ResourceConfig { public JerseyConfig() { // 注册你的资源类 register(GreetingResource.class); } } -
配置
web.xml(可选,但推荐):<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.example.jaxrs</param-value> <!-- 你的资源类所在的包 --> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/api/*</url-pattern> <!-- 与 @ApplicationPath 的值保持一致 --> </servlet-mapping> </web-app> -
部署:将你的项目打包成 WAR 文件,然后部署到 Tomcat 等服务器上。
步骤 3:测试服务
启动服务器后,你可以通过浏览器或 API 工具(如 Postman)来访问。
- 访问
http://localhost:8080/your-project-name/api/greeting/hello- 浏览器会显示:
Hello, Jersey!
- 浏览器会显示:
- 访问
http://localhost:8080/your-project-name/api/greeting/hello/John- 浏览器会显示:
Hello, John!
- 浏览器会显示:
创建客户端 (使用 Jersey Client API)
Jersey 提供了一个强大的客户端 API,可以方便地调用其他 REST 服务。
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
public class GreetingClient {
public static void main(String[] args) {
// 创建客户端
Client client = ClientBuilder.newClient();
// 定义目标 URI
WebTarget target = client.target("http://localhost:8080/your-project-name/api/greeting/hello/John");
// 发送 GET 请求,并获取响应
Response response = target.request().get();
// 检查响应状态
if (response.getStatus() == 200) {
// 读取响应实体(字符串)
String entity = response.readEntity(String.class);
System.out.println("Response from REST service: " + entity);
} else {
System.out.println("Failed with HTTP error code: " + response.getStatus());
}
// 关闭响应和客户端
response.close();
client.close();
}
}
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (RESTful) |
|---|---|---|
| 协议 | SOAP (Simple Object Access Protocol) | HTTP |
| 数据格式 | XML (严格遵循 SOAP 规范) | JSON, XML, HTML 等 (更灵活) |
| 风格 | 动作导向 (RPC/Document) | 资源导向 |
| 标准 | Java EE 标准 | Java EE 标准 |
| 优点 | - 协议标准,跨语言、跨平台能力强 - 内置安全、事务等标准 - 适合企业级、金融等对稳定性要求高的场景 |
- 轻量级,简单易用 - 无需额外的协议层,直接使用 HTTP - 非常适合 Web 和移动应用 - 更好的缓存支持 |
| 缺点 | - 协议复杂,开销大 - 学习曲线较陡 - 开发和调试相对麻烦 |
- 缺乏统一的标准,不同实现可能有差异 - 安全、事务等需要自己实现或依赖其他标准 |
| 适用场景 | 企业内部系统集成、与旧系统集成、需要严格契约和安全性的场景。 | 公开 API、Web 应用、移动后端、前后端分离项目。 |
如何选择?
- 如果你需要构建一个标准的、强类型的、与多种语言(.NET, PHP, Python 等)交互的企业级服务,并且对安全性、事务性有较高要求,选择 JAX-WS。
- 如果你正在开发一个现代化的 Web 应用或移动应用的后端 API,希望服务更轻量、更易于理解和扩展,并且前后端是分离的,强烈推荐 JAX-RS,目前绝大多数新的 Java Web 项目都采用 RESTful 风格。
