You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java发送POST格式XML至SOAP Web服务失败求助

解决直接发送SOAP XML到GeoIP服务的问题

作为刚接触SOAP服务的新手,遇到302重定向或400请求错误真的很常见,我帮你一步步排查解决:

一、先修正请求地址,搞定302重定向

你用的http://www.webservicex.net/geoipservice.asmx?op=GetGeoIP是服务的操作说明页面地址,不是实际接收SOAP请求的Endpoint。正确的请求地址应该是不带op参数的基础地址:http://www.webservicex.net/geoipservice.asmx。服务器会根据你SOAP信封里的操作内容自动路由,不用在URL里指定具体操作。

二、设置关键HTTP请求头,避免400错误

直接发送XML时,必须配置两个核心请求头,少一个都可能触发400错误:

  • Content-Type:必须设为text/xml; charset=utf-8,明确告诉服务器这是SOAP格式的XML请求
  • SOAPAction:值要严格匹配服务的操作命名空间,对于GetGeoIP来说,应该是http://www.webserviceX.NET/GetGeoIP(注意大小写和命名空间,一点都不能错)

三、编写格式正确的SOAP信封

SOAP请求不能只发裸的参数,必须包裹在标准的SOAP信封里。给你一个可以直接复用的GetGeoIP请求示例:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetGeoIP xmlns="http://www.webserviceX.NET/">
      <IPAddress>8.8.8.8</IPAddress>
    </GetGeoIP>
  </soap:Body>
</soap:Envelope>

⚠️ 注意:命名空间http://www.webserviceX.NET/必须和服务定义完全一致,包括大小写;IPAddress标签里要填实际要查询的IP,不能留空。

四、Java发送请求的示例代码(无需WSDL生成类)

我把上面的要点整合到了一段可运行的Java代码里,你可以直接测试:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class SoapGeoIPClient {
    public static void main(String[] args) {
        try {
            // 初始化连接,使用正确的Endpoint地址
            URL serviceUrl = new URL("http://www.webservicex.net/geoipservice.asmx");
            HttpURLConnection conn = (HttpURLConnection) serviceUrl.openConnection();

            // 配置请求方法和核心头信息
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
            conn.setRequestProperty("SOAPAction", "http://www.webserviceX.NET/GetGeoIP");
            conn.setDoOutput(true);

            // 构造SOAP请求体
            String soapRequest = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                    + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
                    + " xmlns:xsd=\"http://www.webserviceX.NET/XMLSchema\""
                    + " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                    + "  <soap:Body>"
                    + "    <GetGeoIP xmlns=\"http://www.webserviceX.NET/\">"
                    + "      <IPAddress>8.8.8.8</IPAddress>"
                    + "    </GetGeoIP>"
                    + "  </soap:Body>"
                    + "</soap:Envelope>";

            // 发送请求
            OutputStream outputStream = conn.getOutputStream();
            outputStream.write(soapRequest.getBytes("UTF-8"));
            outputStream.flush();

            // 读取服务响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            StringBuilder responseBuilder = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                responseBuilder.append(line);
            }
            reader.close();
            outputStream.close();
            conn.disconnect();

            // 打印响应结果
            System.out.println("SOAP服务响应:\n" + responseBuilder.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

五、额外排查Tips

  • 如果还是遇到302,检查是否有本地代理强制跳转,或者服务器是否已切换到HTTPS(目前这个服务还是HTTP协议,应该没问题)
  • 如果400错误依旧,仔细核对SOAP信封的每个标签、命名空间,SOAP对格式的严谨性要求很高,哪怕一个字母大小写错了都会报错
  • 可以先用Postman测试:新建POST请求,填入正确Endpoint,设置好两个核心请求头,粘贴SOAP XML到请求体,确认能拿到响应后,再对照调整Java代码

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

火山引擎 最新活动