WebService 的核心思想是跨平台、跨语言的远程通信,它使用标准的 XML 格式进行数据交换,并通过 HTTP 协议进行传输,在 Java 生态中,主要有三种技术来实现 WebService 调用:

- JAX-WS (Java API for XML Web Services):这是 Java 官方标准,是当前最主流、最成熟的技术,它简化了 SOAP (Simple Object Access Protocol) WebService 的创建和调用。
- JAX-RS (Java API for RESTful Web Services):这是用于创建 RESTful Web 服务的 Java API,虽然严格来说它不叫 "WebService"(传统上指 SOAP),但现在它已成为 Web 服务领域的事实标准,因其轻量、简单而被广泛使用。
- Apache CXF / Axis2:这些都是强大的第三方框架,它们不仅支持 JAX-WS 和 JAX-RS 标准,还提供了更多高级功能和企业级支持。
下面我们分别对这几种方式进行详细说明,并提供代码示例。
JAX-WS (SOAP WebService)
JAX-WS 是 Java EE 的一部分,无需额外引入复杂框架,非常适合标准的、强类型的、需要高安全性的企业级应用。
服务端 创建
你需要一个服务端来提供 WebService。
步骤:

- 定义一个服务接口(SEI - Service Endpoint Interface)。
- 使用
@WebService注解标记该接口。 - 创建一个服务实现类(SIB - Service Implementation Bean)。
- 使用
@WebService和@WebEndpoint等注解实现接口。 - 通过 Endpoint 类发布服务。
代码示例:
接口 HelloService.java
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 定义这是一个 WebService 接口
// targetNamespace 指定了命名空间,通常使用倒包名
@WebService(name = "HelloService", targetNamespace = "http://service.example.com/")
// SOAPBinding.Style.RPC 表示使用 RPC 风格
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloService {
// @WebMethod 指定这是一个对外暴露的 Web 方法
@WebMethod
String sayHello(String name);
}
实现类 HelloServiceImpl.java
import javax.jws.WebService;
// @WebService(endpointInterface = "com.example.service.HelloService")
// 指定该实现类实现了哪个接口
@WebService(endpointInterface = "com.example.service.HelloService")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
System.out.println("Server received request for: " + name);
return "Hello, " + name + "!";
}
}
发布服务 Publisher.java

import javax.xml.ws.Endpoint;
public class Publisher {
public static void main(String[] args) {
// 定义服务的访问地址
String address = "http://localhost:8080/hello";
// 创建服务实现类的实例
HelloService helloService = new HelloServiceImpl();
// 发布服务
Endpoint.publish(address, helloService);
System.out.println("WebService has been published successfully!");
System.out.println("You can access it at: " + address + "?wsdl");
}
}
运行 Publisher,你的 SOAP WebService 就在 http://localhost:8080/hello 启动了,在浏览器中访问这个地址加上 ?wsdl 参数(如 http://localhost:8080/hello?wsdl),可以看到服务的 WSDL (Web Services Description Language) 文件,它描述了服务的所有接口。
客户端 调用
客户端有两种主要方式调用:动态代理和静态客户端。
动态代理(推荐)
这是最简单的方式,你只需要知道服务的 WSDL 地址即可。
代码示例:
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
public class JaxWsClient {
public static void main(String[] args) throws Exception {
// 1. 指定 WSDL 文件的地址
URL wsdlUrl = new URL("http://localhost:8080/hello?wsdl");
// 2. 定义服务的命名空间和服务名
// 这些值可以从 WSDL 文件中找到
QName qname = new QName("http://service.example.com/", "HelloServiceService");
// 3. 创建 Service 实例
Service service = Service.create(wsdlUrl, qname);
// 4. 获取服务端点接口的代理对象
HelloService helloService = service.getPort(HelloService.class);
// 5. 像调用本地方法一样调用远程方法
String result = helloService.sayHello("World");
System.out.println("Client received result: " + result);
}
}
静态客户端(通过 wsimport 工具生成)
这种方式需要先使用 JDK 自带的 wsimport 工具根据 WSDL 文件生成客户端代码。
-
生成客户端代码: 打开命令行,执行以下命令:
wsimport -keep -p com.example.client http://localhost:8080/hello?wsdl
-keep:生成源代码。-p:指定生成代码的包名。- 后面是 WSDL 的 URL。
执行后,会在
com.example.client包下生成一堆 Java 文件(接口、实现类等)。 -
使用生成的代码调用:
import com.example.client.HelloService; import com.example.client.HelloServiceService; public class StaticJaxWsClient { public static void main(String[] args) { // 创建服务实例 HelloServiceService service = new HelloServiceService(); // 获取服务端口 HelloService helloPort = service.getHelloServicePort(); // 调用方法 String result = helloPort.sayHello("Static Client"); System.out.println("Client received result: " + result); } }
JAX-RS (RESTful WebService)
REST (Representational State Transfer) 是一种更现代、更轻量级的架构风格,它通常使用 JSON 作为数据交换格式,通过 HTTP 动词(GET, POST, PUT, DELETE)来操作资源。
在 Java 中,实现 RESTful 服务最流行的框架是 Jersey 和 RESTEasy,这里以 Jersey 为例。
服务端 创建
步骤:
- 添加 Jersey 依赖。
- 创建一个资源类(Resource Class),并用
@Path、@GET、@POST等注解来定义资源和 HTTP 方法。 - 配置并启动一个内嵌的 HTTP 服务器(如 Grizzly)来部署资源。
Maven 依赖 (pom.xml)
<dependencies>
<!-- Jersey 核心依赖 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>2.39</version>
</dependency>
<!-- 支持 JSON -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.39</version>
</dependency>
</dependencies>
资源类 UserResource.java
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<Long, User> userDB = new HashMap<>();
private long idCounter = 1;
// GET 请求,获取所有用户
@GET
@Produces(MediaType.APPLICATION_JSON) // 指定返回 JSON 格式
public List<User> getAllUsers() {
return new ArrayList<>(userDB.values());
}
// GET 请求,根据 ID 获取单个用户
@GET
@Path("{id}") // 路径参数
@Produces(MediaType.APPLICATION_JSON)
public Response getUserById(@PathParam("id") long id) {
User user = userDB.get(id);
if (user == null) {
// 返回 404 Not Found
return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
}
// 返回 200 OK 和用户对象
return Response.ok(user).build();
}
// POST 请求,创建新用户
@POST
@Consumes(MediaType.APPLICATION_JSON) // 指定接收 JSON 格式
@Produces(MediaType.APPLICATION_JSON)
public Response createUser(User user) {
user.setId(idCounter++);
userDB.put(user.getId(), user); 