WebService 的核心思想是跨平台、跨语言的远程调用,它使用 XML/SOAP/WSDL 等标准协议,使得不同技术栈(如 Java, C#, Python)的应用程序能够相互通信。

Java 开发 WebService 主要有两种主流技术栈:
- JAX-WS (Java API for XML Web Services):这是 Java 官方、成熟的 WebService 技术,是 Java EE(Jakarta EE)的一部分,它通常用于构建基于 SOAP 协议的 WebService。
- JAX-RS (Java API for RESTful Web Services):这是用于构建 RESTful 风格 Web 服务的 API,虽然严格来说 RESTful 风格的 Web 服务不总是符合 WebService 的经典定义(SOAP/WSDL),但在现代开发中,它已经成为了事实上的 WebService 开发标准,尤其是在微服务架构中。
下面我将分别详细介绍这两种技术的开发方法。
JAX-WS (SOAP WebService) 开发
JAX-WS 是传统企业级应用中非常常用的技术,它将底层的 SOAP 和 WSDL 复杂性进行了封装,让开发者可以用类似开发普通 Java 类的方式来创建 WebService。
核心概念
- Endpoint (端点):Web 服务的访问地址,是一个 URL。
- SEI (Service Endpoint Interface):服务端点接口,一个 Java 接口,定义了 WebService 可以对外暴露的方法。
- SIB (Service Implementation Bean):服务端点实现,一个 Java 类,实现了 SEI 接口,包含了具体的业务逻辑。
- WSDL (Web Services Description Language):一个 XML 文件,用于描述 WebService 的功能、接口、地址、消息格式等,客户端可以通过 WSDL 了解如何调用服务。
- SOAP (Simple Object Access Protocol):一种简单的、基于 XML 的协议,用于在 Web 上交换结构化的信息。
开发步骤(以最简单的方式为例)
这里我们使用 JDK 自带的 wsimport 工具和 Endpoint 类,无需任何额外框架。

第1步:创建服务端实现类
这是一个普通的 Java 类,我们将在其中实现业务逻辑。
// src/com/example/service/HelloServiceImpl.java
package com.example.service;
import javax.jws.WebService;
import javax.jws.WebMethod;
// 使用 @WebService 注解标记这个类作为一个 WebService
@WebService
public class HelloServiceImpl {
// 使用 @WebMethod 注解标记要暴露为 WebService 方法的方法
@WebMethod
public String sayHello(String name) {
return "Hello, " + name + "! Welcome to JAX-WS World.";
}
@WebMethod
public int add(int a, int b) {
return a + b;
}
}
第2步:发布 WebService
创建一个主类,使用 javax.xml.ws.Endpoint 来发布我们的服务。
// src/com/example/publisher/Publisher.java
package com.example.publisher;
import com.example.service.HelloServiceImpl;
import javax.xml.ws.Endpoint;
public class Publisher {
public static void main(String[] args) {
// 定义 WebService 的访问地址
String address = "http://localhost:8888/ws/hello";
// 创建服务实现对象
Object implementor = new HelloServiceImpl();
// 发布服务
Endpoint.publish(address, implementor);
System.out.println("WebService is published at: " + address);
}
}
运行 Publisher 类,现在你的 WebService 就已经启动了。
第3步:测试 WebService
打开浏览器,访问你在 Publisher 中定义的地址:http://localhost:8888/ws/hello

你会看到一个 WSDL 文件的链接,通常名为 ?wsdl,点击它,可以看到服务的完整定义 XML。
使用 wsimport 生成客户端代码:
打开命令行(CMD 或 PowerShell),执行以下命令:
# -p: 客户端代码的包名 # -d: 生成的代码存放目录 # -keep: 保留生成的源文件 wsimport -p com.example.client -d ./client -keep http://localhost:8888/ws/hello?wsdl
执行后,会在 ./client 目录下生成一堆 Java 文件(包括 SEI 的实现类、Service 类等)。
第4步:编写客户端调用代码
在新生成的客户端代码中,你会找到一个 HelloServiceImplService 类(Service 的子类),这是客户端的入口。
// src/com/example/client/ClientTest.java
package com.example.client;
public class ClientTest {
public static void main(String[] args) {
// 创建服务实例 (通过 Service 类)
HelloServiceImplService service = new HelloServiceImplService();
// 获取服务端点接口 (SEI) 的代理对象
HelloServiceImpl helloService = service.getHelloServiceImplPort();
// 像调用本地方法一样调用远程方法
String result1 = helloService.sayHello("Alice");
System.out.println(result1);
int result2 = helloService.add(10, 20);
System.out.println("10 + 20 = " + result2);
}
}
运行 ClientTest,如果一切正常,你将看到控制台输出:
Hello, Alice! Welcome to JAX-WS World.
10 + 20 = 30
JAX-RS (RESTful WebService) 开发
RESTful 风格是目前 Web 服务开发的主流,它更轻量、更简单,通常基于 HTTP 协议,使用 JSON 作为数据交换格式。
核心概念
- 资源:REST 的核心是将一切视为资源(如用户、订单、产品),每个资源都有一个唯一的 URI。
- HTTP 方法:
GET:获取资源。POST:创建资源。PUT:更新资源(全量)。DELETE:删除资源。PATCH:部分更新资源。
- 无状态:服务器不保存客户端的状态,每个请求都包含处理该请求所需的所有信息。
- 数据格式:通常使用 JSON 或 XML。
开发步骤(使用 JAX-RS 的参考实现 Jersey)
虽然 JDK 不包含 JAX-RS 的实现,但 Jersey 是最流行、功能最全的实现之一。
第1步:添加依赖(Maven)
在 pom.xml 中添加 Jersey 核心依赖。
<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.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.39</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.39</version>
</dependency>
</dependencies>
第2步:配置 web.xml
在 webapp/WEB-INF/web.xml 中配置 Jersey Servlet。
<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.rest</param-value>
<!-- 告诉 Jersey 在哪个包下查找资源类 -->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
<!-- 所有以 /rest/ 开头的请求都由 Jersey 处理 -->
</servlet-mapping>
</web-app>
第3步:创建资源类
这是 RESTful 服务的核心,用注解来映射 URI 和 HTTP 方法。
// src/com/example/rest/UserResource.java
package com.example.rest;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
@Path("/users") // 定义资源的基础路径
public class UserResource {
// 模拟一个数据库
private static Map<Integer, User> userDB = new HashMap<>();
private static int currentId = 3; 