- JAX-WS (Java API for XML Web Services):这是 Java 标准的 WebService 技术,非常成熟、稳定,广泛用于企业级应用,它通常使用 SOAP (Simple Object Access Protocol) 协议进行通信。
- 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 的一部分,所以如果你使用的是像 Tomcat 这样的 Web 服务器,你需要引入额外的库(如 jaxws-rt),如果使用像 JBoss/WildFly 这样的应用服务器,则通常已经内置了支持。
这里我们以最常用的方式:使用 JDK 内置的 wsimport 工具生成客户端,并手动编写服务端为例。
环境准备
- JDK 8 或更高版本
- 一个 Web 服务器,如 Apache Tomcat (9.x)
- 一个 IDE,如 IntelliJ IDEA 或 Eclipse
服务端开发
步骤 1:创建 Maven Web 项目
在 IDEA 或 Eclipse 中创建一个新的 Maven Web 项目。

步骤 2:添加依赖
在 pom.xml 文件中添加 JAX-WS 的运行时库。jaxws-rt 是一个非常流行的实现,它可以在 Tomcat 等非 Java EE 容器中运行。
<dependencies>
<!-- JAX-WS RI (Reference Implementation) -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
步骤 3:编写服务接口 (SEI - Service Endpoint Interface)
这个接口定义了 WebService 提供的方法,它必须使用 @WebService 注解。

// src/main/java/com/example/service/UserService.java
package com.example.service;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
@WebService
public interface UserService {
/**
* 根据用户ID获取用户信息
* @param userId 用户ID
* @return 用户信息字符串
*/
@WebMethod
String getUserInfo(@WebParam(name = "userId") String userId);
/**
* 欢迎方法
* @param name 用户名
* @return 欢迎字符串
*/
@WebMethod
String sayHello(@WebParam(name = "name") String name);
}
步骤 4:编写服务实现类 (SIB - Service Implementation Bean)
这个类实现了上面定义的接口。
// src/main/java/com/example/service/UserServiceImpl.java
package com.example.service;
import javax.jws.WebService;
@WebService(endpointInterface = "com.example.service.UserService")
public class UserServiceImpl implements UserService {
@Override
public String getUserInfo(String userId) {
// 模拟业务逻辑
if ("001".equals(userId)) {
return "User ID: 001, Name: Zhang San, Email: zhangsan@example.com";
} else {
return "User not found.";
}
}
@Override
public String sayHello(String name) {
return "Hello, " + name + "!";
}
}
步骤 5:发布 WebService
你需要一个类来启动并发布这个服务,这个类通常会在 Web 应用启动时被调用。
// src/main/java/com/example/publisher/WebServicePublisher.java
package com.example.publisher;
import com.example.service.UserServiceImpl;
import javax.xml.ws.Endpoint;
public class WebServicePublisher {
public static void main(String[] args) {
// 定义WebService的发布地址
String address = "http://localhost:8080/myapp/userService";
// 创建服务实现类实例
UserServiceImpl userServiceImpl = new UserServiceImpl();
// 发布WebService
Endpoint.publish(address, userServiceImpl);
System.out.println("WebService is published at: " + address);
}
}
注意:Endpoint.publish() 这种方式主要用于开发和测试,在生产环境中,通常会将 WebService 部署到 Servlet 容器中,通过 web.xml 进行配置。
步骤 6:部署和测试
-
运行发布类:直接运行
WebServicePublisher的main方法。 -
访问 WSDL:打开浏览器,访问
http://localhost:8080/myapp/userService?wsdl,如果看到一个 XML 文件,说明服务发布成功,这个 WSDL 文件是客户端用来调用服务的“说明书”。 -
测试客户端:可以使用
wsimport命令行工具生成客户端代码进行测试。# 在命令行执行,-p 指定包名,-keep 保留生成的文件 wsimport -p com.example.client -keep http://localhost:8080/myapp/userService?wsdl
执行后,会在
com.example.client包下生成一堆 Java 文件(如UserService、UserService_Service等),然后你可以编写一个简单的 Java 客户端来调用:// 客户端调用代码 import com.example.client.UserService; import com.example.client.UserService_Service; public class JaxWsClientTest { public static void main(String[] args) { // 创建服务视图 UserService_Service service = new UserService_Service(); // 获取服务端口 UserService userService = service.getUserServicePort(); // 调用远程方法 String helloResult = userService.sayHello("World"); System.out.println(helloResult); String userInfoResult = userService.getUserInfo("001"); System.out.println(userInfoResult); } }
使用 JAX-RS (RESTful WebService)
JAX-RS 的标准实现是 Jersey 和 RESTEasy,这里我们以 Jersey 为例,因为它也是由 Oracle (Sun) 官方提供的参考实现。
环境准备
- JDK 8 或更高版本
- 一个 Web 服务器,如 Apache Tomcat (9.x)
- 一个 IDE,如 IntelliJ IDEA 或 Eclipse
服务端开发
步骤 1:创建 Maven Web 项目
步骤 2:添加依赖
在 pom.xml 中添加 Jersey 的核心依赖。
<dependencies>
<!-- Jersey 2.x 核心依赖 -->
<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-jackson</artifactId>
<version>2.35</version>
</dependency>
</dependencies>
步骤 3:配置 web.xml
告诉 Servlet 容器如何初始化 Jersey。
<!-- 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.resource</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>
步骤 4:创建资源类 (Resource Class)
这是 JAX-RS 的核心,使用注解来映射 HTTP 请求。
// src/main/java/com/example/resource/UserResource.java
package com.example.resource;
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 Map<String, User> userDB = new HashMap<>();
public UserResource() {
userDB.put("1", new User("1", "Alice", "alice@example.com"));
userDB.put("2", new User("2", "Bob", "bob@example.com"));
}
// GET /api/users/1
@GET
@Path("/{userId}")
@Produces(MediaType.APPLICATION_JSON) // 指定返回格式为 JSON
public Response getUserById(@PathParam("userId") String userId) {
User user = userDB.get(userId);
if (user == null) {
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
return Response.ok(user).build();
}
// GET /api/users
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<User> getAllUsers() {
return new ArrayList<>(userDB.values());
}
// POST /api/users
@POST
@Consumes(MediaType.APPLICATION_JSON) // 指定接收格式为 JSON
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
userDB.put(user.getId(), user);
return Response.status(Response.Status.CREATED).entity(user).build();
}
}
// 一个简单的 POJO 类
class User {
private String id;
private String name;
private String email;
// 构造器、getters 和 setters 是必须的
public User() {}
public User(String id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// Getters and Setters
public String getId() { return id; }
public void setId(String 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; }
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
步骤 5:部署和测试
-
将项目打包成
.war文件并部署到 Tomcat。 -
启动 Tomcat。
-
使用 API 测试工具(如 Postman, curl 或浏览器)进行测试。
-
获取所有用户:
GET http://localhost:8080/myapp/api/users预期响应:[ {"id":"1","name":"Alice","email":"alice@example.com"}, {"id":"2","name":"Bob","email":"bob@example.com"} ] -
获取单个用户:
GET http://localhost:8080/myapp/api/users/1预期响应:{"id":"1","name":"Alice","email":"alice@example.com"} -
创建新用户:
POST http://localhost:8080/myapp/api/users请求体 (Body):{ "id": "3", "name": "Charlie", "email": "charlie@example.com" }预期响应:
{"id":"3","name":"Charlie","email":"charlie@example.com"}
-
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (REST) |
|---|---|---|
| 协议 | SOAP (基于 XML,有严格标准) | HTTP (GET, POST, PUT, DELETE 等) |
| 数据格式 | 主要是 XML | 主要是 JSON,也支持 XML |
| 风格 | 面向接口,契约优先 | 面向资源,无状态 |
| 复杂度 | 较高,配置繁琐 | 较低,简单直观 |
| 性能 | 较低,SOAP 头部开销大 | 较高,轻量级 |
| 适用场景 | 企业级应用,需要高安全性、事务支持、ACID 合规的场景 | Web 和移动应用 API,前后端分离架构 |
| 工具支持 | WSDL 自动生成客户端/服务端代码 | 通常需要手动编写或使用 Swagger 生成文档 |
如何选择?
- 如果你的项目是传统的企业应用,需要与 .NET 等其他平台进行复杂的、事务性的交互,并且安全性要求极高,JAX-WS 是一个可靠的选择。
- 如果你正在构建一个现代化的 Web 应用或移动 App 的后端 API,追求开发效率、性能和前后端分离,JAX-RS (RESTful) 几乎是必然的选择,目前绝大多数新项目都采用 RESTful 风格。
