在 Java 生态中,创建 Web Service 主要有两种主流技术:

- JAX-WS (Java API for XML Web Services):这是 Java 官方、标准的 Web Service 技术,主要用于构建基于 SOAP(Simple Object Access Protocol)协议的 Web Service,它非常成熟,在企业级应用中广泛使用。
- JAX-RS (Java API for RESTful Web Services):这是用于构建 RESTful Web Service 的标准 API,它使用 HTTP 协议方法(GET, POST, PUT, DELETE 等)和资源(通常是 URI)来操作数据,格式通常是 JSON 或 XML,现代 Web 应用(尤其是移动端和前后端分离项目)中非常流行。
下面我将分别提供这两种技术的完整源码示例和详细讲解。
示例 1:使用 JAX-WS (SOAP) 创建 Web Service
JAX-WS 的实现者中最著名的是 Apache CXF 和 JDK 自带的 Metro,这里我们使用 Apache CXF,因为它功能更强大、更灵活。
第 1 步:创建 Maven 项目并添加依赖
在 pom.xml 文件中添加 CXF 的核心依赖:
<dependencies>
<!-- JAX-WS 核心依赖 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.5.5</version> <!-- 建议使用较新版本 -->
</dependency>
<!-- CXF 的 Jetty 服务器依赖,用于内嵌运行服务 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
第 2 步:创建服务接口和实现类
这是 Web Service 的核心,定义了服务能做什么。

服务接口 (IHelloWorldService.java)
使用 @WebService 注解来标记这是一个 Web Service 接口。
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService(name = "HelloWorld", // 服务名
targetNamespace = "http://service.example.com/") // 命名空间,通常使用包的反向
public interface IHelloWorldService {
/**
* 获取问候语
* @param name 用户名
* @return 问候信息
*/
@WebMethod
String sayHello(@WebParam(name = "userName") String name);
/**
* 计算两数之和
* @param a
* @param b
* @return 和
*/
@WebMethod
int add(@WebParam(name = "numA") int a, @WebParam(name = "numB") int b);
}
服务实现类 (HelloWorldServiceImpl.java)
实现接口,使用 @WebService 注解标记实现类。
import javax.jws.WebService;
@WebService(endpointInterface = "com.example.service.IHelloWorldService",
serviceName = "HelloWorld") // 指定接口和服务的名称
public class HelloWorldServiceImpl implements IHelloWorldService {
@Override
public String sayHello(String name) {
System.out.println("Server: sayHello 被调用了, name = " + name);
return "你好, " + name + "! 欢迎使用 JAX-WS Web Service.";
}
@Override
public int add(int a, int b) {
System.out.println("Server: add 被调用了, a = " + a + ", b = " + b);
return a + b;
}
}
第 3 步:发布 Web Service
创建一个主类来启动内嵌的 Jetty 服务器并发布我们的服务。
ServerStarter.java

import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class ServerStarter {
public static void main(String[] args) {
// 1. 创建 JaxWsServerFactoryBean 实例
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
// 2. 设置服务实现的实例
factory.setServiceBean(new HelloWorldServiceImpl());
// 3. 设置服务的发布地址 (Endpoint Address)
factory.setAddress("http://localhost:8080/ws/hello");
// 4. 创建并启动服务
factory.create();
System.out.println("Web Service 已成功启动!");
System.out.println("访问地址: http://localhost:8080/ws/hello?wsdl");
System.out.println("你可以使用工具如 SoapUI 或 wsimport 来测试此服务。");
}
}
第 4 步:运行和测试
- 运行服务:直接运行
ServerStarter的main方法。 - 验证 WSDL:在浏览器中访问
http://localhost:8080/ws/hello?wsdl,如果看到一个 XML 文件(WSDL 定义),说明服务发布成功。 - 客户端测试:
- 使用 JDK 自带工具
wsimport# 在项目根目录或任意位置执行,会生成客户端调用代码 wsimport -keep -p com.example.client http://localhost:8080/ws/hello?wsdl
- 使用 SoapUI 创建一个新项目,输入 WSDL 地址,即可进行图形化测试。
- 使用 JDK 自带工具
示例 2:使用 JAX-RS (RESTful) 创建 Web Service
JAX-RS 的标准实现中,Jersey 和 RESTEasy 是最流行的,这里我们使用 Jersey。
第 1 步:创建 Maven 项目并添加依赖
在 pom.xml 文件中添加 Jersey 的核心依赖:
<dependencies>
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<!-- Jersey 2.x 版本 -->
<version>2.39.1</version>
</dependency>
<!-- 如果需要支持 JSON (Jackson) -->
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.39.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.39.1</version>
</dependency>
</dependencies>
第 2 步:创建资源类
在 REST 中,服务被抽象为“资源”,用普通的 Java 类表示,并用注解来描述其行为。
User.java (一个简单的实体类)
public class User {
private String name;
private int id;
// 构造器、getter 和 setter
public User() {}
public User(int id, String name) {
this.id = id;
this.name = name;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
}
UserService.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;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Path("/users") // 定义资源的基路径
public class UserService {
// 模拟一个数据库
private static ConcurrentMap<Integer, User> userDB = new ConcurrentHashMap<>();
static {
userDB.put(1, new User(1, "张三"));
userDB.put(2, new User(2, "李四"));
}
// @GET: 处理 HTTP GET 请求
// @Path: 定义子路径
// @Produces: 定义返回的媒体类型
@GET
@Path("/{userId}")
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam("userId") int userId) {
System.out.println("Server: 获取用户 ID = " + userId);
return userDB.get(userId);
}
// @POST: 处理 HTTP POST 请求
// @Consumes: 定义接受的请求体媒体类型
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
System.out.println("Server: 创建用户 " + user);
userDB.put(user.getId(), user);
// 返回 201 Created 状态码和创建的资源
return Response.status(Response.Status.CREATED).entity(user).build();
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<User> getAllUsers() {
System.out.println 