binding定义“怎么调用”,即协议和消息格式;service定义“在哪调用”,即网络地址。二者通过port的binding属性关联,一个binding可被多个port复用,但一个port只能绑定一个binding。

binding 标签定义的是「怎么调用」
<binding> 描述某个 <portType>(即接口契约)在具体协议下的实现细节。它不关心服务部署在哪,只管“用什么协议、什么格式、怎么发请求”。常见绑定是 SOAP 1.1 / 1.2,但也支持 HTTP GET/POST 或甚至 SMTP。
关键点:
-
<soap:binding>的style属性决定是document还是rpc风格;transport指定底层协议,比如http://schemas.xmlsoap.org/soap/http - 每个
<operation>在 binding 中必须对应一个<soap:operation>,并明确其soapAction(SOAP 1.1 必需,1.2 可省略) - 输入/输出消息的序列化方式由
<soap:body>的use(literal或encoded)和namespace控制,这直接影响生成客户端代码时的参数结构
service 标签定义的是「在哪能调用」
<service> 是 WSDL 文档的终点——它把某个 <binding> 和真实的网络地址关联起来。没有 <service>,你就知道“能怎么调”,但不知道“往哪发”。
典型结构里,<service> 包含一个或多个 <port>,每个 <port> 引用一个 <binding> 并给出 <soap:address location="...">。
注意:
-
<port>的name通常和<binding>名一致,但不是强制;真正绑定靠的是binding属性的 QName(如tns:MyBinding) -
location值必须是完整 URL(含协议、主机、路径),且不能是相对路径;很多工具(如 Java 的 wsimport)会直接把这个地址写死进生成的 Stub 类 - 一个 service 可以有多个 port,例如同时暴露 SOAP over HTTP 和 SOAP over HTTPS 的 binding,方便客户端按需选择
binding 和 service 不是一对一关系
一个 <binding> 可被多个 <port> 复用,只要它们指向不同地址;反过来,一个 <port> 只能绑定一个 <binding>。
常见误用场景:
- 修改了服务端部署路径(比如从
http://a.com/svc换成http://b.com/api),只改了<service>里的location,却忘了同步更新所有引用该 WSDL 的客户端——因为很多框架缓存或硬编码了旧地址 - WSDL 中定义了两个 binding(如 SOAP 1.1 和 SOAP 1.2),但
<service>下只给了一个<port>,导致客户端无法自动发现另一套协议支持 - 用工具生成客户端时,选错了 port(比如选了 test 环境的 port 却部署到 prod),而错误提示常是 “Connection refused” 或 “404”,而非明确指出地址错配
<wsdl:service name="StockQuoteService">
<wsdl:port name="StockQuotePort" binding="tns:StockQuoteBinding">
<soap:address location="https://api.example.com/stockquote"/>
</wsdl:port>
</wsdl:service>
WSDL 里最易被忽略的其实是 <port> 和 <binding> 之间的 QName 引用是否拼写一致——大小写、命名空间前缀差一个字符,解析就会失败,但错误信息往往只报 “invalid binding reference”,不指明哪一行。










