抛弃各种平台所提供的标准或框架(如JAX-WS, Axis, Spring-WS) ,我们回到最原始的WebService技术。我们只需要操控SOAP协议数据,用HTTP的方式传送于client和server之间,也可以享受到WebService所提供的服务。只是比较麻烦。
UDDI
首先需要寻找我们需要的WebService服务. 对于提供商来说,要想让别人能过发现自己提供的服务,就需要将自己的服务注册到某一类公共的发布栏中去。这一系列的标准,被称为UDDI。我们可以通过在UDDI目录中搜索,得到我们想要的服务。
这里,我们使用一个全球天气预报的WebService: http://www.webservicex.net/globalweather.asmx?WSDL
WSDL
WSDL的结构示意图如下:
现在,我们要对天气预报的WSDL进行分析。
查看WebService的描述文件,看看提供了什么样子的接口。
首先查看WSDL提供的service:
从上面可以看出,WSDL中,Service提供了4个port,每个port声明一个binding与address的绑定。注意,不同的协议在展示地址的时候所用的标签命名空间也不同, 例如soap, soap12, http.
我们打算使用Soap12协议的port,于是我们将查看binding="tns:GlobalWeatherSoap12"的定义。
通过上面的binding定义,我们看到,此binding实现了PortType tns:GlobalWeatherSoap的operation, 并声明使用soap12协议。在Operation的实现中,如何组装input和output。从上面的代码,我们可以得出
Request的请求应该是PortType GlobalWeatherSoap的input:
http://www.webservicex.net/globalweather.asmx HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>
</soap12:Body>
</soap12:Envelope>
Response的响应应该是PortType GloableWeatherSoap的output:
<?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>
</soap12:Body>
</soap12:Envelope>
接下来,我们来组装Request Body .
依照PortType GloableWeatherSoap的定义:
Operation GetWeather的input是Message GetWeatherSoapIn, 而output是Message GetWeatherSoapOut. 找到Message的定义
两个Message均引用了XSD Type,一个是GetWeather, 另一个是GetWeatherResponse, 找到两个type的定义:
这时候,我们可以根据上面对Input Type和Output Type的定义,可以填充request和response的soap:body了。
最终的请求应该为:
http://www.webservicex.net/globalweather.asmx HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>
<GetWeather xmlns="http://www.webserviceX.NET">
<CityName>shanghai</CityName>
<CountryName>China</CountryName>
</GetWeather>
</soap12:Body>
</soap12:Envelope>
最终的响应应该为:
<?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>
<GetWeatherResponse xmlns="http://www.webserviceX.NET">
<GetWeatherResult>text</GetWeatherResult>
</GetWeatherResponse>
</soap12:Body>
</soap12:Envelope>
Fiddler
接下来,我们使用Fiddler来测试一下上面所有的推断。 打开Fiddler, 在Composer tab中,贴入我们的Request.
点击execute以后,到Inspectors tab里面,查看response:
Java实现
接下来,我们使用Java的net包和JAXP来实现webservice的调用。
public class App {
public static void main( String[] args ) throws IOException, ParserConfigurationException, SAXException {
StringBuilder sb = new StringBuilder();
sb.append( "<?xml version=\"1.0\" encoding=\"utf-8\"?> ")
.append( " <soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
.append( " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ")
.append( " xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\"> ")
.append( " <soap12:Body> ")
.append( " <GetWeather xmlns=\"http://www.webserviceX.NET\"> ")
.append( " <CityName>shanghai</CityName> ")
.append( " <CountryName>China</CountryName> ")
.append( " </GetWeather> ")
.append( " </soap12:Body> ")
.append( " </soap12:Envelope> ");
URL url = new URL("http://www.webservicex.net/globalweather.asmx");
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestProperty("Content-Length", String.valueOf(sb.length()));
httpConn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
OutputStream out = httpConn.getOutputStream();
out.write(sb.toString().getBytes());
out.close();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(httpConn.getInputStream());
String body = doc.getElementsByTagName("GetWeatherResult").item(0).getChildNodes().item(0).getNodeValue();
System.out.println(body);
}
}
最后输出为:
<?xml version="1.0" encoding="utf-16"?>
<CurrentWeather>
<Location>Shanghai / Hongqiao, China (ZSSS) 31-10N 121-26E 3M</Location>
<Time>Apr 17, 2014 - 05:30 AM EDT / 2014.04.17 0930 UTC</Time>
<Wind> from the NNW (340 degrees) at 9 MPH (8 KT) (direction variable):0</Wind>
<Visibility> 1 mile(s):0</Visibility>
<Temperature> 66 F (19 C)</Temperature>
<DewPoint> 59 F (15 C)</DewPoint>
<RelativeHumidity> 77%</RelativeHumidity>
<Pressure> 29.83 in. Hg (1010 hPa)</Pressure>
<Status>Success</Status>
</CurrentWeather>
来源:oschina
链接:https://my.oschina.net/u/254689/blog/223513