该Demo用到了天气预报公共开放接口, 数据来源于中国气象局
Endpoint : www.webxml.com.cn/WebServices…
Disco : www.webxml.com.cn/WebServices…
WSDL : www.webxml.com.cn/WebServices…
什么是WSDL
WSDL(Web Services Description Language,Web服务描述语言)是一种用于描述Web服务接口的XML格式的语言。它定义了Web服务的功能、操作和消息格式,允许客户端应用程序了解如何与特定的Web服务进行交互。
主要组成部分包括:
- 服务定义(Service Definition) : 描述服务的名称、命名空间和服务的位置(URL)
- 端口类型(Port Type) : 定义一个抽象接口, 包含一组操作(operations)
- 绑定(Binding) : 将端口类型映射到具体的协议和消息格式, 如SOAP协议的HTTP绑定
- 消息(Message) : 定义数据元素和类型, 用于消息的结构
WSDL使得客户端能够理解如何构造有效的请求,并处理来自服务端的响应。它为Web服务提供了标准化的描述,使得不同平台和编程语言的应用程序可以互相通信和交互。
看不懂? 没关系, 因为我也看不懂
举个例子, 访问 www.webxml.com.cn/WebServices… 可以看到WSDL的文档, 如下图所示
啊这一大堆密密麻麻的是什么东西啊?! 看得我头皮发麻! 但实际上, 看WSDL文档需要从末尾看起, 我们把页面拉到最底下
我们能看到一些带有binding属性的标签, 以12结尾说明支持soap 1.2, 如果没有则说明只支持soap 1.1, 至于什么是SOAP, 这个我们一会再说, 接着来看WSDL文档
这种形式的就是接口定义了, 那么这东西要怎么看呢? 其实也很简单, name标签后为接口名, 例如图中第一个接口名为getSupportProvince
sequence标签下的内容展示了需要传递的参数, 例如getSupportProvince接口不需要传参, 而getSupportProvinceResponse接口需要传递String[]类型的参数getSupportProvinceResult
那么怎么传递参数呢? 这就要说到SOAP了
什么是SOAP
SOAP协议(Simple Object Access Protocol,简单对象访问协议)是一种用于交换结构化信息在分布式环境中进行通信的协议。它基于XML,用于在网络上通过HTTP或其他协议传输信息。SOAP协议主要用于不同系统之间的通信,可以支持不同平台和编程语言的互操作性。
SOAP消息通常由一个envelope(信封)、一个header(头)、一个body(主体)和一个fault(错误)组成。SOAP协议提供了一种标准的、简单的方法来访问Web服务,并且可以通过WSDL(Web Services Description Language,Web服务描述语言)定义服务接口。
啊怎么办, 我还是看不懂啊! 别急别急, 俗话说万事开头难, 然后中间难, 最后结尾难...要是不用上班也能拿工资就好了, 咳咳
扯远了, 还是回来看看SOAP, 协议其实大概就是这样一种形式
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
...
...
</soap:Header>
<soap:Body>
...
...
<soap:Fault>
...
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
举个例子, 这里就不作详解了, 需要看详解的朋友可以看看站内的这篇文章
将string替换为需要传参的内容即可, 如果传送的参数是XML字符串, 那么需要使用转义或者使用<![CDATA[ + xmlStr + ]]>, 建议使用<![CDATA[ + xmlStr + ]]>的方式
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getSupportCity xmlns="http://WebXml.com.cn/">
<byProvinceName>string</byProvinceName>
</getSupportCity>
</soap12:Body>
</soap12:Envelope>
注意区分SOAP的版本和命名空间
SOAP 1.1 schemas.xmlsoap.org/soap/envelo…
SOAP 1.2 www.w3.org/2003/05/soa…
最后附上样例代码
代码样例
方法示例
public String httpClient(String url, String soap) {
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
String result = null;
byte[] bytes = soap.getBytes(StandardCharsets.UTF_8);
try (BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(bytes, 0, bytes.length))) {
// SOAP 1.1 uses "text/xml"
// SOAP 1.2 uses "application/soap+xml"
RequestEntity re = new InputStreamRequestEntity(bis, bytes.length, "application/soap+xml;charset=utf-8");
postMethod.setRequestEntity(re);
httpClient.executeMethod(postMethod);
result = postMethod.getResponseBodyAsString();
} catch (IOException e) {
e.printStackTrace();
} finally {
postMethod.releaseConnection();
}
return result;
}
调用示例
@Test
public void httpClient() {
String url = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl";
String soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">\n" +
" <soap12:Body>\n" +
" <getSupportCity xmlns=\"http://WebXml.com.cn/\">\n" +
" <byProvinceName>江苏</byProvinceName>\n" +
" </getSupportCity>\n" +
" </soap12:Body>\n" +
"</soap12:Envelope>";
String s = httpClient(url, soap);
System.out.println(s);
}