核心概念:Java WebService 是什么?
在开始交互之前,我们首先要明白 Java WebService 通常提供什么样的接口,最常见和标准化的有两种:

-
SOAP (Simple Object Access Protocol)
- 特点:一种基于 XML 的协议,格式非常严格和规范,它使用 WSDL (Web Services Description Language) 文件来描述服务的接口、方法、参数和返回值类型。
- 优点:标准化程度高,具有强大的安全性和事务支持,适合企业级应用。
- 缺点:协议相对复杂,数据包较大,性能开销比 REST 高。
- Java 实现:Java 中实现 SOAP WebService 的主流框架是 JAX-WS (Java API for XML Web Services),Apache CXF、Metro 等都是基于 JAX-WS 的。
-
REST (Representational State Transfer)
- 特点:一种更轻量级的架构风格,而不是一个严格的协议,它通常通过 HTTP 协议以 JSON 或 XML 格式传输数据,操作方式符合 HTTP 方法(GET, POST, PUT, DELETE)。
- 优点:简单、灵活、易于理解和扩展,性能较好,是目前最主流的 WebService 形式。
- 缺点:缺乏像 SOAP 那样的标准化约束,安全性通常需要自己实现(如 OAuth, JWT)。
- Java 实现:Java 中实现 RESTful WebService 的主流框架是 JAX-RS (Java API for RESTful Web Services),最著名的实现是 Jersey 和 RESTEasy。
PHP 与 Java WebService 的交互,主要就是指 PHP 如何消费(调用)Java 提供的 SOAP 或 REST 服务。
交互方式详解
我们将分别讨论如何与这两种服务进行交互。

调用 SOAP WebService
调用 SOAP 服务的关键是获取服务的 WSDL 文件地址,PHP 有一个内置的扩展 SoapClient 可以非常方便地处理 SOAP 协议。
步骤:
- 获取 Java 服务的 WSDL 文件 URL。
- 在 PHP 中实例化
SoapClient,并传入 WSDL 地址。 - 通过
SoapClient对象直接调用服务端的方法。
示例代码
假设有一个 Java WebService,提供根据用户ID获取用户信息的功能。

Java 服务端 (JAX-WS 示例)
这是一个简化的 Java 服务端代码,它有一个 getUserInfo 方法。
// UserService.java
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
@WebService
public class UserService {
@WebMethod
public UserInfo getUserInfo(@WebParam(name = "userId") String userId) {
System.out.println("PHP is requesting info for user: " + userId);
// 模拟从数据库查询
if ("123".equals(userId)) {
UserInfo user = new UserInfo();
user.setId("123");
user.setName("John Doe");
user.setEmail("john.doe@example.com");
return user;
}
return null;
}
}
// UserInfo.java - 这是一个简单的POJO (Plain Old Java Object)
public class UserInfo {
private String id;
private String name;
private String 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; }
}
部署后,你会得到一个 WSDL 文件,http://your-java-server.com/UserService?wsdl
PHP 客户端
<?php
// 1. WSDL 文件的 URL
$wsdlUrl = 'http://your-java-server.com/UserService?wsdl';
try {
// 2. 实例化 SoapClient
// options: ['trace' => true] 可以帮助调试,它会记录请求和响应的 XML
$client = new SoapClient($wsdlUrl, ['trace' => 1]);
// 3. 准备参数
$params = ['userId' => '123'];
// 4. 调用 Java WebService 的方法
// 方法名 'getUserInfo' 必须与 Java 服务端 @WebMethod 注解中的名称一致
$response = $client->getUserInfo($params);
// 5. 处理响应
echo "--- Request XML ---\n";
echo $client->__getLastRequest() . "\n\n"; // 获取发送的XML
echo "--- Response XML ---\n";
echo $client->__getLastResponse() . "\n\n"; // 获取接收的XML
echo "--- PHP Result ---\n";
// $response 对象的结构会根据 WSDL 定义的返回值自动生成
// 对于上面的例子,它会是一个 stdClass 对象,或者你可以使用 WSDL 的类映射
var_dump($response);
if (property_exists($response, 'return')) {
// 注意:复杂对象的返回值通常被包装在一个名为 'return' 的属性中
echo "User Name: " . $response->return->name . "\n";
echo "User Email: " . $response->return->email . "\n";
}
} catch (SoapFault $e) {
// 捕获 SOAP 错误
echo "SOAP Error: " . $e->getMessage() . "\n";
echo "Error Code: " . $e->faultcode . "\n";
echo "Error Detail: " . $e->detail . "\n";
} catch (Exception $e) {
// 捕获其他错误
echo "Error: " . $e->getMessage() . "\n";
}
?>
调用 REST WebService
调用 REST 服务本质上是发送 HTTP 请求,PHP 中有多种方式可以实现,从内置函数到强大的第三方库。
步骤:
- 确定 REST 服务的 API 端点(URL)、HTTP 方法(GET/POST/PUT/DELETE)、请求头(如
Content-Type: application/json)和请求体(如果是 POST/PUT)。 - 在 PHP 中构造并发送 HTTP 请求。
- 接收并解析响应体(通常是 JSON)。
PHP 实现方式对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| cURL | 功能强大,灵活,是 PHP 的标准扩展 | 代码相对繁琐,需要手动设置各种选项 | 几乎所有场景,特别是需要精细控制请求时 |
| Guzzle | 现代化、面向对象、链式调用、异常处理、测试友好 | 需要通过 Composer 安装(composer require guzzlehttp/guzzle) |
强烈推荐,适合新项目,能极大提升开发效率 |
| file_get_contents | 极其简单,无需额外扩展 | 不够灵活,无法处理复杂的请求(如设置自定义头、上传文件等),容易超时 | 仅适用于非常简单的 GET 请求 |
示例代码
假设有一个 Java REST 服务,提供获取用户列表的功能,URL 为 http://your-java-server.com/api/users,返回 JSON 数据。
Java 服务端 (JAX-RS 示例)
// UserResource.java
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Arrays;
import java.util.List;
@Path("/api/users")
public class UserResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<UserInfo> getUsers() {
// 模拟从数据库查询
return Arrays.asList(
new UserInfo("1", "Alice", "alice@example.com"),
new UserInfo("2", "Bob", "bob@example.com")
);
}
}
PHP 客户端
我们将展示三种方式。
方式 A:使用 cURL
<?php
$url = 'http://your-java-server.com/api/users';
// 初始化 cURL
$ch = curl_init($url);
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将响应作为字符串返回,而不是直接输出
curl_setopt($ch, CURLOPT_HEADER, false); // 不包含响应头
// 如果需要发送 POST 数据
// curl_setopt($ch, CURLOPT_POST, true);
// curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['key' => 'value']));
// 执行请求
$response = curl_exec($ch);
// 检查是否有错误
if (curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch);
} else {
// 获取 HTTP 状态码 