SOAP 与 HTTP 协议绑定(SOAP over HTTP)——最完整、最实用的总结
几乎所有实际项目中,SOAP 消息都是通过 HTTP(偶尔 HTTPS) 传输的,这被称为 SOAP HTTP Binding(SOAP over HTTP)。它在 W3C 规范里叫 SOAP HTTP Protocol Binding。
1. 为什么几乎都用 HTTP?
- 防火墙友好(默认 80/443 端口几乎都放行)
- 开发工具链成熟(几乎所有语言都有现成 SOAP 栈)
- 可以直接复用 HTTP 状态码、Content-Type、认证机制等
2. 标准的 HTTP 请求格式(最常见的样子)
POST /StockQuoteService HTTP/1.1
Host: www.example.com
Content-Type: text/xml; charset=utf-8 <-- 关键!SOAP 1.1
-- 或者 SOAP 1.2 用下面这个 --
-- Content-Type: application/soap+xml; charset=utf-8
SOAPAction: "http://example.com/GetStockPrice" <-- SOAP 1.1 必须有(可以为空字符串)
Content-Length: 512
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetStockPrice xmlns:m="http://example.com/stock">
<m:Symbol>IBM</m:Symbol>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
3. Content-Type 和 SOAPAction 对比表(超重要)
| 版本 | Content-Type | SOAPAction 头部 | 备注 |
|---|---|---|---|
| SOAP 1.1 | text/xml; charset=utf-8 | 必须存在(可以是 "") | 绝大多数银行、运营商、老系统都是这个 |
| SOAP 1.2 | application/soap+xml; charset=utf-8 | 可选(推荐省略) | 新系统、.NET WCF、JAX-WS 默认 1.2 就是这个 |
| SOAP 1.2 + action 参数 | application/soap+xml; charset=utf-8; action="http://example.com/action" | 可省略 | 部分框架会把 action 写到 Content-Type 里 |
4. 标准的 HTTP 响应格式
成功响应(200 OK):
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 456
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetStockPriceResponse xmlns:m="http://example.com/stock">
<m:Price>83.8</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>
错误响应(通常 500 Internal Server Error):
HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf-8
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>系统异常,请稍后重试</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
5. HTTP 状态码与 SOAP Fault 的常见对应关系(实际项目中最常用的约定)
| HTTP 状态码 | 常见场景 | Body 中通常放什么 |
|---|---|---|
| 200 OK | 业务成功(最常见) | 正常响应 |
| 400 Bad Request | 客户端参数错误、XML 格式错 | 一般放 soap:Client Fault |
| 401 Unauthorized | 需要 WS-Security、Basic Auth 等认证失败 | 通常直接 HTTP 401,也可能返回 Fault |
| 403 Forbidden | 权限不足 | Fault 或直接 403 |
| 404 Not Found | 服务路径错误 | 一般不返回 SOAP,直接 404 |
| 405 Method Not Allowed | 用了 GET 而服务只支持 POST | 直接 405 |
| 415 Unsupported Media Type | Content-Type 不是 text/xml 或 application/soap+xml | 直接 415 |
| 500 Internal Server Error | 服务器异常、业务抛异常 | 必须返回 soap:Server Fault |
| 502/503 | 网关超时、后端服务不可用 | 很多系统会返回 500 + Fault |
6. 真实世界中最常见的两种情况
- 国内银行、运营商、政府接口(99% 是这个)
POST /webservice/xxx.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
- 国外或较新系统(Java Spring Boot + JAX-WS、.NET Core)
POST /api/soap HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
7. 用 curl 测试 SOAP 接口的标准命令
SOAP 1.1(最常见):
curl -X POST https://www.example.com/service \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: \"\"" \
-d @request.xml
SOAP 1.2:
curl -X POST https://www.example.com/service \
-H "Content-Type: application/soap+xml; charset=utf-8" \
-d @request.xml
一句话总结:
SOAP + HTTP = 永远用 POST + 正确的 Content-Type + (SOAP 1.1 时)必带 SOAPAction 头,响应永远是 200 或 500 并在 Body 里放正常消息或 Fault。
如果你现在要对接某个具体的接口,把 WSDL 地址或请求示例贴给我,我可以立刻告诉你它到底是 SOAP 1.1 还是 1.2、该怎么写 HTTP 头。