You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用w3school.com的SOAP服务失败,遇两种异常求助

问题分析与解决办法

嘿,咱们来拆解一下你遇到的两个SOAP服务调用问题,以及对应的解决思路:

1. 核心问题:收到HTML而非SOAP响应

你碰到的XmlPullParserException是最关键的信号——服务返回的是<html>页面,完全不是预期的<soap:Envelope>格式响应。这大概率不是代码的锅,而是以下几种情况:

  • w3school的旧SOAP服务已经下线或地址变更,现在访问原来的端点会直接跳转到官网页面;
  • 请求的URL写错了,指向了w3school的普通网页而非SOAP接口的专属端点;
  • HTTP请求头配置不全,比如没加Content-Type: text/xml; charset=utf-8或SOAPAction头,导致服务根本识别不出这是SOAP请求。

2. 先验证SOAP服务是否还能用

建议先用Postman或者curl手动发个SOAP请求测试一下端点:
比如针对之前的CurrencyConverter服务,正确的请求格式应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ConversionRate xmlns="http://www.webserviceX.NET/">
      <FromCurrency>USD</FromCurrency>
      <ToCurrency>EUR</ToCurrency>
    </ConversionRate>
  </soap:Body>
</soap:Envelope>

如果发送后返回的还是HTML,那这个服务肯定是用不了了,建议换个更稳定的测试SOAP服务,比如经典的.NET计算器服务,端点地址是www.dneonline.com/calculator.asmx。

3. 解决「Stream Closed」异常的思路

第一次遇到的流关闭异常,通常是这几个原因导致的:

  • HTTP连接超时设置太短,响应还没读完就断开了;
  • 代码里错误地提前关闭了输入流或者Transport连接;
  • 服务端因为请求格式不对,主动断开了连接。

4. 具体修复步骤

  • 更换可用的测试服务:用刚才说的计算器服务,它的SOAP格式清晰,长期稳定;
  • 完善请求配置:确保设置正确的请求头和合理的超时时间,示例代码如下:
// 初始化KeepAliveTransport,设置10秒的连接和读取超时
KeepAliveHttpsTransportSE transport = new KeepAliveHttpsTransportSE("www.dneonline.com", 443, "/calculator.asmx", 10000, 10000);

// 配置必要的SOAP请求头
List<Header> headers = new ArrayList<>();
headers.add(new Header("Content-Type", "text/xml; charset=utf-8"));
headers.add(new Header("SOAPAction", "\"http://tempuri.org/Add\""));
transport.setHeaders(headers);

// 构造加法请求的SOAP消息
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true; // 适配.NET编写的服务
SoapObject request = new SoapObject("http://tempuri.org/", "Add");
request.addProperty("intA", 10);
request.addProperty("intB", 20);
envelope.setOutputSoapObject(request);

// 发送请求并处理响应
try {
    transport.call(null, envelope);
    SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
    System.out.println("计算结果:" + response.toString());
} catch (Exception e) {
    e.printStackTrace();
    // 打印服务返回的完整错误内容,方便排查问题
    if (transport.getErrorStream() != null) {
        String errorContent = new BufferedReader(
            new InputStreamReader(transport.getErrorStream())
        ).lines().collect(Collectors.joining("\n"));
        System.out.println("服务返回的错误内容:\n" + errorContent);
    }
}
  • 添加错误日志:捕获异常时打印服务返回的完整内容,这能帮你快速判断是请求写错了,还是服务本身不可用。

内容的提问来源于stack exchange,提问作者Margerite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:53:18