目录
- 什么是 WebService? - 核心概念
- WebService 的两种主流风格
- SOAP (JAX-WS)
- RESTful (JAX-RS)
- 环境准备
- 实战教程:使用 JAX-WS (SOAP) 开发 WebService
- 第一步:创建服务端
- 第二步:创建客户端
- 第三步:测试与运行
- 实战教程:使用 JAX-RS (RESTful) 开发 WebService
- 第一步:添加依赖
- 第二步:创建资源类
- 第三步:配置 Web 部署描述符
- 第四步:部署与测试
- JAX-WS vs. JAX-RS:如何选择?
- 进阶学习资源
什么是 WebService?
核心思想: WebService 是一种跨编程语言、跨操作系统、跨网络的应用程序通信技术,它允许不同的应用程序通过标准的 Web 协议(主要是 HTTP)进行交互和数据交换。

核心特点:
- 跨平台: 基于 XML 或 JSON 等标准数据格式,任何平台上的任何应用都可以解析。
- 跨语言: 服务端可以用 Java 写,客户端可以用 Python、C#、JavaScript 等调用。
- 基于标准: 遵循 WSDL (Web Services Description Language) 等标准,方便发现和使用。
- 通过 HTTP 通信: 可以轻松穿过防火墙,因为 HTTP (80/443 端口) 是几乎所有网络都允许的。
简单比喻: 你可以把 WebService 想象成一个“餐厅服务员”,你的客户端(顾客)通过 HTTP(走进餐厅)向服务员(WebService)发出请求(点菜单),服务员将你的请求传递给后厨(服务端逻辑),后厨做好菜(处理请求),再由服务员将结果(数据)端回给你。
WebService 的两种主流风格
开发 Java WebService 主要有两种技术规范,分别对应两种不同的架构风格。
A. SOAP (Simple Object Access Protocol) - JAX-WS
- 风格: 一种协议,规定了消息的格式、处理方式等,它非常严格和重量级。
- 消息格式: XML,消息体被封装在一个严格的
<SOAP-Envelope>结构中。 - 描述语言: WSDL (Web Services Description Language),一个 XML 文件,详细描述了服务的地址、可用的方法、参数、返回值类型等,客户端可以通过 WSDL 文件自动生成调用代码。
- Java 规范: JAX-WS (Java API for XML Web Services),这是 Java 官方提供的用于创建和消费 SOAP WebService 的 API。
- 优点: 标准化程度高、安全可靠、支持事务。
- 缺点: 协议复杂、消息体积大、解析慢。
- 适用场景: 企业级应用(如银行、金融、电信)、对安全性要求高、需要严格事务管理的系统。
B. RESTful (Representational State Transfer) - JAX-RS
- 风格: 一种软件架构风格,而不是一个协议,它更轻量、更灵活。
- 消息格式: JSON (最常用) 或 XML,格式非常简洁,易于人阅读和机器解析。
- 描述方式: 通常没有像 WSDL 那样的描述文件,API 的定义通常通过 URL 路径、HTTP 方法来体现。
- Java 规范: JAX-RS (Java API for RESTful Web Services),这是 Java 官方提供的用于创建 RESTful WebService 的 API。
- 优点: 轻量、简单、性能好、易于理解和使用,非常适合移动端和前端。
- 缺点: 无状态、缺少标准的安全和事务机制(需要自己实现或补充)。
- 适用场景: 公开 API (如微博、微信 API)、移动应用后端、Web 前后端分离项目。
环境准备
- JDK: 安装 JDK 8 或更高版本。
- IDE: 推荐使用 IntelliJ IDEA 或 Eclipse。
- Web 服务器: Tomcat (9.x 或更高版本) 是最常用的选择,我们将在教程中使用它。
- 构建工具: Maven (强烈推荐)。
实战教程:使用 JAX-WS (SOAP)
我们将创建一个简单的 HelloWorld WebService。

第一步:创建服务端
-
创建 Maven Web 项目 在你的 IDE 中创建一个新的 Maven 项目,选择
maven-archetype-webapp模板。 -
添加依赖 打开
pom.xml,添加 JAX-WS API 依赖,如果你使用 JDK 9+,可能还需要添加java.xml.ws模块。<dependencies> <!-- JAX-WS API --> <dependency> <groupId>javax.xml.ws</groupId> <artifactId>jaxws-api</artifactId> <version>2.3.1</version> </dependency> <!-- 为了在 Tomcat 上运行,需要一个 JAX-WS 实现服务器,JAX-WS RI --> <!-- 这会帮你处理 WSDL 生成等底层工作 --> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <version>2.3.3</version> </dependency> </dependencies> -
创建服务端接口 创建一个 Java 接口,并使用
@WebService注解来标记它。// src/main/java/com/example/HelloService.java package com.example; import javax.jws.WebService; import javax.jws.WebMethod; // @WebService 注解将这个接口声明为一个 WebService @WebService public interface HelloService { // @WebMethod 注解将这个方法暴露为 WebService 的一个操作 @WebMethod String sayHello(String name); } -
创建服务端实现类 创建一个实现上述接口的类。
(图片来源网络,侵删)// src/main/java/com/example/HelloServiceImpl.java package com.example; import javax.jws.WebService; // implementFrom 指定实现的是哪个接口 @WebService(endpointInterface = "com.example.HelloService") public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "Hello, " + name + "! Welcome to JAX-WS World."; } } -
发布 WebService 创建一个发布服务的类,通常使用
Endpoint类。// src/main/java/com/example/Publisher.java package com.example; import javax.xml.ws.Endpoint; import javax.xml.ws.WebServiceException; public class Publisher { public static void main(String[] args) { // 定义 WebService 的发布地址 String address = "http://localhost:8080/ws/hello"; try { // 发布服务 Endpoint.publish(address, new HelloServiceImpl()); System.out.println("WebService is published at: " + address); System.out.println("WSDL is available at: " + address + "?wsdl"); System.out.println("Press any key to stop the server..."); System.in.read(); // 阻塞主线程,保持服务运行 } catch (WebServiceException e) { System.err.println("Failed to publish service: " + e.getMessage()); } catch (Exception e) { e.printStackTrace(); } } } -
运行服务端 运行
Publisher类的main方法,控制台会打印出服务地址和 WSDL 地址。
第二步:创建客户端
JAX-WS 最强大的功能之一就是可以根据 WSDL 文件自动生成客户端代码。
-
使用 wsimport 工具生成客户端代码 打开你的命令行,切换到项目根目录(
pom.xml所在目录),执行以下 Maven 命令:# -DgenerateClient=true 会自动调用 wsimport # -DwsdlLocation 指定 WSDL 文件的路径 mvn clean compile jaxws:wsimport -DgenerateClient=true -DwsdlLocation="http://localhost:8080/ws/hello?wsdl"
执行成功后,你会在
target/generated-sources/jaxws目录下看到一堆生成的 Java 文件(.java)和类文件(.class)。 -
创建客户端调用类 在
src/main/java下创建一个客户端类来调用服务。// src/main/java/com/example/HelloClient.java package com.example; import javax.xml.namespace.QName; import javax.xml.ws.Service; import java.net.URL; public class HelloClient { public static void main(String[] args) throws Exception { // WSDL 文件的地址 URL wsdlUrl = new URL("http://localhost:8080/ws/hello?wsdl"); // 定义服务的命名空间和名称 QName qname = new QName("http://example.com/", "HelloServiceImplService"); // 创建 Service 实例 Service service = Service.create(wsdlUrl, qname); // 获取服务端点接口的代理对象 HelloService helloService = service.getPort(HelloService.class); // 调用远程方法 String response = helloService.sayHello("WebService Client"); System.out.println("Response from server: " + response); } } -
运行客户端 确保服务端正在运行,然后运行
HelloClient的main方法,你将看到控制台输出:Response from server: Hello, WebService Client! Welcome to JAX-WS World.
实战教程:使用 JAX-RS (RESTful)
我们将创建一个简单的用户管理 RESTful API。
第一步:添加依赖
在 pom.xml 中添加 JAX-RS API 和一个实现(如 Jersey)的依赖。
<dependencies>
<!-- JAX-RS API -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<!-- Jersey 作为 JAX-RS 的实现 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.34</version>
</dependency>
</dependencies>
第二步:创建资源类
资源类是处理 HTTP 请求的核心,它包含各种处理方法。
// src/main/java/com/example/UserResource.java
package com.example;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
// @Path 注解定义了这个资源的基 URI
@Path("/users")
public class UserResource {
// 模拟一个数据库
private static Map<Integer, String> userDB = new HashMap<>();
private static int currentId = 1;
// @GET 注解表示处理 GET 请求
// @Produces 注解指定返回的媒体类型
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<String> getAllUsers() {
return new ArrayList<>(userDB.values());
}
// @Path 可以嵌套,定义更具体的路径
// @PathParam 用于从 URL 路径中提取参数
@GET
@Path("/{userId}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserById(@PathParam("userId") int userId) {
String user = userDB.get(userId);
if (user == null) {
// @Status 定义 HTTP 状态码
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
return Response.ok(user).build();
}
// @POST 注解表示处理 POST 请求
// @Consumes 注解指定请求体的媒体类型
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(String userName) {
int newId = currentId++;
userDB.put(newId, userName);
// 返回 201 Created 状态码和新创建资源的 URI
return Response.status(Response.Status.CREATED).entity("User created with ID: " + newId).build();
}
}
第三步:配置 Web 部署描述符
为了让 Tomcat 知道如何处理 JAX-RS 请求,我们需要配置 web.xml。
<!-- src/main/webapp/WEB-INF/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</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>
</servlet-mapping>
</web-app>
第四步:部署与测试
-
部署到 Tomcat 将你的项目打包成 WAR 文件(使用
mvn clean package),然后部署到 Tomcat 服务器中。 -
测试 API 你可以使用 Postman、curl 或浏览器来测试这些 API。
-
获取所有用户 (GET)
http://localhost:8080/你的项目名/api/users(首次访问,应返回[]) -
创建用户 (POST) 使用 Postman,设置 POST 请求到
http://localhost:8080/你的项目名/api/users。 在 Body -> raw -> JSON 中输入:"Alice"应返回201 Created和消息User created with ID: 1 -
再次获取所有用户 (GET) 再次访问
http://localhost:8080/你的项目名/api/users,应返回["Alice"] -
根据 ID 获取用户 (GET) 访问
http://localhost:8080/你的项目名/api/users/1,应返回Alice访问http://localhost:8080/你的项目名/api/users/999,应返回404 Not Found
-
JAX-WS vs. JAX-RS:如何选择?
| 特性 | JAX-WS (SOAP) | JAX-RS (RESTful) |
|---|---|---|
| 风格 | 协议 | 架构风格 |
| 消息格式 | XML (严格) | JSON/XML (灵活) |
| 描述语言 | WSDL (标准) | 无标准 (通常由 API 文档描述) |
| 状态 | 支持有状态/无状态 | 天然无状态 |
| 性能 | 较慢 (XML 解析开销大) | 较快 (JSON 轻量) |
| 复杂度 | 高 | 低 |
| 安全性 | 内置 WS-Security 标准 | 需自己实现 (如 OAuth, JWT) |
| 最佳场景 | 企业内部系统、金融、EDI | 公开 API、移动后端、前后端分离 |
简单决策:
- 如果你的服务需要与企业内部遗留的 SOAP 系统集成,或者对安全、事务有非常严格的要求,选择 JAX-WS。
- 如果你要开发一个面向公众或移动端的 API,希望它简单、快速、易于前端调用,选择 JAX-RS。
在当今的开发中,JAX-RS (RESTful) 的使用频率远高于 JAX-WS。
进阶学习资源
- JAX-WS:
- JAX-RS (Jersey):
- Spring 框架集成:
- 现实世界中,很少有人直接使用 JAX-WS/JAX-RS 的原生 API,更常见的是使用 Spring 框架来简化开发。
- Spring Web Services: 用于构建 SOAP 服务。
- Spring Boot Web / Spring REST: 用于构建 RESTful 服务,这是目前最主流的方式。
- 工具:
- Postman / Insomnia: 强大的 API 测试工具。
- SoapUI: 专门用于测试 SOAP 服务的工具。
- cURL: 命令行工具,适合快速测试 API。
希望这份详细的教程能帮助你入门 Java WebService!祝你学习愉快!
