- JAX-WS (Java API for XML Web Services):这是 Java 标准的 WebService 技术,基于 SOAP 协议,它简单、成熟,广泛用于企业级应用。(推荐用于新项目,尤其是与旧系统集成时)
- JAX-RS (Java API for RESTful Web Services):这是 Java 标准的 RESTful WebService 技术,基于 HTTP 协议和 JSON/XML 数据格式,它更轻量、更灵活,是目前 Web 开发的主流选择。(推荐用于构建现代的、前后端分离的应用)
下面我将分别详细介绍这两种方式,并提供完整的代码示例。

使用 JAX-WS 发布 SOAP WebService
JAX-WS 是 Java EE 的一部分,因此如果你使用的是 Tomcat 这样的 Web 服务器,需要额外引入 JAX-WS 的实现库,最常用的是 JAX-WS RI (Reference Implementation),也就是 Metro。
环境准备
你需要以下 JAR 包(如果你使用 Maven,会自动处理依赖):
jaxws-api.jarjaxws-rt.jar(核心运行时库)jakarta.xml.ws-api.jar(如果你使用 Jakarta EE 9+)jakarta.xml.bind-api.jar(如果你使用 Jakarta EE 9+)stax-api.jarstreambuffer.jar
最简单的方式是使用 Maven,在你的 pom.xml 中添加以下依赖:
<dependencies>
<!-- JAX-WS RI 核心依赖 -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>3.0.2</version> <!-- 使用较新版本 -->
</dependency>
</dependencies>
编写 WebService 接口和实现类
定义一个服务接口,并使用 @WebService 注解。

UserService.java (接口)
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 指定这是一个 WebService 接口
@WebService
// @SOAPBinding 指定 SOAP 消息风格为文档类型
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public interface UserService {
// @WebMethod 指定这是一个对外暴露的方法
@WebMethod
String sayHello(String name);
@WebMethod
User getUserInfo(String userId);
}
User.java (一个简单的数据传输对象 DTO)
public class User {
private String id;
private String name;
private int age;
// 必须有无参构造函数
public User() {}
public User(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 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 int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "User{id='" + id + "', name='" + name + "', age=" + age + "}";
}
}
UserServiceImpl.java (实现类)
import javax.jws.WebService;
// serviceName 指定服务的名称,endpointInterface 指定服务的接口
@WebService(serviceName = "UserService", endpointInterface = "com.example.UserService")
public class UserServiceImpl implements UserService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "!";
}
@Override
public User getUserInfo(String userId) {
// 模拟从数据库获取用户信息
if ("001".equals(userId)) {
return new User("001", "张三", 30);
}
return null;
}
}
发布 WebService
发布 WebService 有两种方式:独立发布 和 集成到 Web 容器(如 Tomcat)。
方案 A:独立发布 (Standalone)
这种方式不依赖任何 Web 服务器,直接通过 Java main 方法启动服务。
import javax.xml.ws.Endpoint;
public class Publisher {
public static void main(String[] args) {
// 创建服务实现类的实例
UserServiceImpl userService = new UserServiceImpl();
// 发布服务
// 第一个参数是服务的访问地址
// 第二个参数是服务的实现类实例
Endpoint.publish("http://localhost:8080/ws/user", userService);
System.out.println("WebService 已成功发布在 http://localhost:8080/ws/user");
}
}
运行 Publisher.java,然后你可以使用 SoapUI 或浏览器访问 http://localhost:8080/ws/user?wsdl 来查看 WSDL 文件。
方案 B:集成到 Web 容器 (如 Tomcat)
这是更常见的企业级做法,你需要一个监听器来在 Web 应用启动时自动发布服务。
创建 web.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 使用 JAX-WS 提供的监听器 -->
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<!-- 配置 Servlet -->
<servlet>
<servlet-name>UserWebService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.XSServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserWebService</servlet-name>
<url-pattern>/ws/user</url-pattern>
</servlet-mapping>
</web-app>
创建 sun-jaxws.xml 文件
这个文件用于配置要发布的 WebService。
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<!--
id: 唯一标识
implementation: 服务实现类的全限定名
url-pattern: 与 web.xml 中的 servlet-mapping 对应
-->
<endpoint
id="user"
implementation="com.example.UserServiceImpl"
url-pattern="/ws/user"/>
</endpoints>
部署到 Tomcat
将你的 Web 应用打包成 WAR 文件,并部署到 Tomcat 的 webapps 目录下,启动 Tomcat,服务就会自动发布。
访问地址同样是:http://localhost:8080/你的项目名/ws/user?wsdl
使用 JAX-RS 发布 RESTful WebService
JAX-RS 是 Java EE 的一部分,其最流行的参考实现是 Jersey,Spring Boot 内置了对 JAX-RS 的支持,但更推荐使用其自带的 Spring Web (Spring MVC) 来构建 REST API,因为它更简单、更强大。
这里我们介绍在 传统 Java Web 项目 中使用 Jersey 发布 RESTful 服务。
环境准备
在 pom.xml 中添加 Jersey 依赖:
<dependencies>
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-servlet</artifactId>
<version>3.1.2</version> <!-- 使用较新版本 -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.1.2</version>
</dependency>
<!-- 支持 JSON 格式 -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
编写 Resource (资源类)
在 JAX-RS 中,我们称之为 "Resource"(资源),它对应一个具体的 URL 路径。
UserResource.java
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
// @Path 定义了资源的基路径
@Path("/users")
public class UserResource {
// 模拟一个用户数据库
private static List<User> userList = new ArrayList<>();
static {
userList.add(new User("001", "张三", 30));
userList.add(new User("002", "李四", 25));
}
// @GET 表示这是一个 HTTP GET 请求
// @Path 定义子路径
// @Produces 定义响应的媒体类型,这里是 JSON
@GET
@Path("/{userId}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserById(@PathParam("userId") String userId) {
for (User user : userList) {
if (user.getId().equals(userId)) {
return Response.ok(user).build(); // 返回 200 OK 状态码和用户对象
}
}
// 如果用户不存在,返回 404 Not Found
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
// @POST 表示这是一个 HTTP POST 请求
// @Consumes 定义请求体的媒体类型,这里是 JSON
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
userList.add(user);
// 返回 201 Created 状态码和创建的用户对象
return Response.status(Response.Status.CREATED).entity(user).build();
}
// @GET 不带参数,获取所有用户
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<User> getAllUsers() {
return userList;
}
}
配置和发布
方案 A:集成到 Web 容器 (如 Tomcat)
这是最常用的方式。
创建 web.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<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>
<!-- 配置 Jersey 扫描的包 -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example</param-value> <!-- 你的 Resource 类所在的包 -->
</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>
部署到 Tomcat 将项目打包成 WAR 文件并部署到 Tomcat。
测试 API 启动 Tomcat 后,你可以使用 Postman 或浏览器来测试你的 REST API:
-
获取所有用户:
- URL:
http://localhost:8080/你的项目名/rest/users - Method:
GET - Response:
[{ "id": "001", "name": "张三", "age": 30 }, { "id": "002", "name": "李四", "age": 25 }]
- URL:
-
获取特定用户:
- URL:
http://localhost:8080/你的项目名/rest/users/001 - Method:
GET - Response:
{ "id": "001", "name": "张三", "age": 30 }
- URL:
-
创建新用户:
- URL:
http://localhost:8080/你的项目名/rest/users - Method:
POST - Body (raw, JSON):
{ "id": "003", "name": "王五", "age": 28 } - Response (Status 201 Created):
{ "id": "003", "name": "王五", "age": 28 }
- URL:
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (REST) |
|---|---|---|
| 协议 | SOAP (XML) | HTTP (JSON/XML/Text 等) |
| 风格 | 面向动作,定义操作 | 面向资源,定义资源 |
| 格式 | 严格规范的 XML | 灵活的 JSON/XML 等 |
| 标准 | Java EE 标准 | Java EE 标准 |
| 使用场景 | 企业级应用,与旧系统集成,需要高安全性和事务支持 | 现代Web应用,移动端API,前后端分离 |
| 工具/库 | JAX-WS RI (Metro), Apache CXF | Jersey, RESTEasy, Spring Web |
| 发布方式 | 独立发布 / Web容器 | 主要集成到Web容器 |
如何选择?
- 如果你的项目需要与传统的、基于 SOAP 的企业服务(如 .NET 服务)集成,或者你的公司有严格的 SOAP 标准,JAX-WS 是一个可靠的选择。
- 如果你要构建一个新的、现代化的 Web 应用,特别是前后端分离架构,或者你的 API 需要被移动端、单页应用广泛调用,JAX-RS (或更流行的 Spring Web) 是更好的选择,它更轻量、更易于理解和扩展。
