杰瑞科技汇

PHP如何调用Java的WebService?

核心概念

我们需要明确几个关键点:

PHP如何调用Java的WebService?-图1
(图片来源网络,侵删)
  1. WebService 协议:最经典和广泛支持的协议是 SOAP (Simple Object Access Protocol),它使用 XML 格式进行数据交换,并通过 WSDL (Web Services Description Language) 文件来描述服务的接口(有哪些方法、参数、返回值类型等),我们这里主要讲解调用 SOAP WebService。
  2. PHP 的 SOAP 扩展:PHP 内置了 SOAP 扩展,这是处理 SOAP 协议最直接、最高效的方式,确保你的 PHP 环境已经启用了这个扩展(在 php.ini 中检查 extension=soap 是否被取消注释)。
  3. Java WebService 框架:Java 世界里创建 WebService 的工具有很多,如 Apache Axis2, Apache CXF, JAX-WS (Java API for XML Web Services) 等,它们生成的 WSDL 文件格式略有不同,但都遵循 SOAP 标准,PHP 客户端的调用方法是通用的。

使用 PHP 原生 SOAP 扩展(最推荐)

这是最标准、最简单、性能最好的方法,PHP 的 SoapClient 类可以直接通过 WSDL 地址来创建客户端,并自动解析所有可用的方法。

步骤 1:获取 WSDL 文件地址

你的 Java WebService 必须提供一个 WSDL 文件,通常这个文件的地址是 http://your-java-server/your-service?wsdl,Java 使用 JAX-WS 框架部署的服务,通常会有这样一个地址。

步骤 2:编写 PHP 客户端代码

假设我们有一个 Java WebService,它提供一个 getUserInfo 方法,需要一个 userId 字符串参数,并返回一个包含用户信息的复杂对象。

创建 PHP 脚本 (client.php)

PHP如何调用Java的WebService?-图2
(图片来源网络,侵删)
<?php
// 1. 设置 WSDL 文件的 URL
$wsdl = 'http://your-java-server/YourService?wsdl';
// 2. 创建 SoapClient 实例
// 第一个参数是 WSDL URL
// 第二个参数是选项数组,'trace' => true 非常有用,可以开启 SOAP 请求/响应的追踪
$client = new SoapClient($wsdl, ['trace' => 1, 'exceptions' => true]);
// 3. 准备调用服务所需的参数
// 参数必须是一个数组,键是参数名,值是对应的值。
// 这个参数名需要和 WSDL 文件中定义的参数名一致。
$params = [
    'userId' => '12345'
];
// 4. 调用 WebService 方法
// 方法名 'getUserInfo' 必须和 WSDL 中定义的操作名一致。
try {
    $result = $client->getUserInfo($params);
    // 5. 处理返回结果
    // $result 是一个 PHP 对象或数组,其结构由 WSDL 定义。
    echo "调用成功!\n";
    echo "返回结果: \n";
    print_r($result);
    // 如果开启了 'trace',可以查看详细的 SOAP 请求和响应
    echo "\n--- SOAP 请求 ---\n";
    echo $client->__getLastRequest();
    echo "\n--- SOAP 响应 ---\n";
    echo $client->__getLastResponse();
} catch (SoapFault $e) {
    // 捕获 SOAP 错误
    echo "SOAP 错误: [{$e->faultcode}] {$e->faultstring}\n";
    echo "请求详情: \n";
    echo $client->__getLastRequest();
} catch (Exception $e) {
    // 捕获其他异常
    echo "发生错误: " . $e->getMessage();
}
?>

运行脚本

在命令行中执行:

php client.php

代码解释

  • new SoapClient($wsdl, [...]): 这是核心,PHP 会自动下载并解析 WSDL 文件,生成一个客户端代理对象,之后你就可以像调用本地方法一样调用远程服务的方法。
  • $params: 参数数组。键名必须与 WSDL 中定义的参数名完全匹配,这是最容易出错的地方,WSDL 中参数是 userId,你就不能用 id
  • $client->getUserInfo($params): 调用方法,PHP 会自动将 PHP 数组/对象序列化为符合 SOAP 规范的 XML 请求,发送给服务器,并接收服务器返回的 XML 响应,然后反序列化为 PHP 的对象或数组。
  • SoapFault: 当服务端返回一个 SOAP 错误(参数类型错误、服务内部错误等)时,会抛出 SoapFault 异常。try...catch 块是必不可少的。
  • __getLastRequest()__getLastResponse(): 当选项中设置 'trace' => 1 时,这两个方法会非常有用,当调用失败时,你可以打印出它们的内容,查看发送了什么 XML 给服务器,服务器又返回了什么 XML,这对于调试非常有帮助。

使用 WSDL 生成 PHP 客户端代码(辅助方法)

WSDL 结构非常复杂,或者你想提前在代码中看到所有可用的方法和参数结构,你可以使用 PHP 内置的 wsdl2php.php 工具来生成一个包装类。

步骤

  1. 找到 wsdl2php.php 工具 这个工具通常位于 PHP 的安装目录下,C:\php\extras\soap\wsdl2php.php (Windows) 或 /usr/share/php/Soap/wsdl2php.php (Linux)。

  2. 运行命令生成代码 在命令行中执行以下命令:

    php /path/to/wsdl2php.php --location=http://your-java-server/YourService?wsdl --output-dir=./generated_client
    • --location: 你的 WSDL 地址。
    • --output-dir: 生成的 PHP 类文件存放的目录。
  3. 使用生成的客户端类 执行命令后,你会在 generated_client 目录下得到一个或多个 PHP 文件(通常一个服务对应一个类文件),然后你就可以在代码中 include 并使用它了。

    <?php
    require_once './generated_client/YourService.php'; // 引入生成的类
    $wsdl = 'http://your-java-server/YourService?wsdl';
    $client = new YourService(['trace' => 1]); // 直接使用生成的类
    $params = ['userId' => '12345'];
    $result = $client->getUserInfo($params);
    print_r($result);
    ?>

    这种方法的好处是代码提示更好(如果你使用 IDE),但通常不如直接使用 SoapClient 简洁。


使用 cURL 手动发送 SOAP 请求(不推荐,仅作了解)

如果因为某些原因(PHP 环境无法安装 SOAP 扩展,或者服务端有特殊的 HTTP 头要求),你不能使用 SoapClient,你可以手动构建 SOAP 请求的 XML,并通过 cURL 发送。

这种方法非常繁琐,因为你需要自己处理 XML 的构建、SOAPAction 头的设置、以及 XML 响应的解析。

<?php
$wsdlUrl = 'http://your-java-server/YourService?wsdl';
$endpointUrl = 'http://your-java-server/YourService'; // 实际的请求地址,可能和 WSDL 不同
// 1. 手动构建 SOAP 请求 XML
$soapRequest = <<<XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://your.service.namespace/">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:getUserInfo>
         <!--Optional:-->
         <ser:userId>12345</ser:userId>
      </ser:getUserInfo>
   </soapenv:Body>
</soapenv:Envelope>
XML;
// 2. 初始化 cURL
$ch = curl_init();
// 3. 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $endpointUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $soapRequest);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: text/xml; charset=utf-8',
    'SOAPAction: "http://your.service.namespace/YourService/getUserInfo"' // SOAPAction 必须和 WSDL 中的 Action 匹配
]);
// 4. 执行请求并获取响应
$response = curl_exec($ch);
// 5. 检查错误
if (curl_errno($ch)) {
    echo 'c
分享:
扫描分享到社交APP
上一篇
下一篇