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




