拋棄各類平臺所提供的標準或框架(如JAX-WS, Axis, Spring-WS) ,咱們回到最原始的WebService技術。咱們只須要操控SOAP協議數據,用HTTP的方式傳送於client和server之間,也能夠享受到WebService所提供的服務。只是比較麻煩。html
首先須要尋找咱們須要的WebService服務. 對於提供商來講,要想讓別人能過發現本身提供的服務,就須要將本身的服務註冊到某一類公共的發佈欄中去。這一系列的標準,被稱爲UDDI。咱們能夠經過在UDDI目錄中搜索,獲得咱們想要的服務。java
這裏,咱們使用一個全球天氣預報的WebService: http://www.webservicex.net/globalweather.asmx?WSDL web
WSDL的結構示意圖以下:app
如今,咱們要對天氣預報的WSDL進行分析。框架
查看WebService的描述文件,看看提供了什麼樣子的接口。測試
首先查看WSDL提供的service:ui
從上面能夠看出,WSDL中,Service提供了4個port,每一個port聲明一個binding與address的綁定。注意,不一樣的協議在展現地址的時候所用的標籤命名空間也不一樣, 例如soap, soap12, http.url
咱們打算使用Soap12協議的port,因而咱們將查看binding="tns:GlobalWeatherSoap12"的定義。spa
經過上面的binding定義,咱們看到,此binding實現了PortType tns:GlobalWeatherSoap的operation, 並聲明使用soap12協議。在Operation的實現中,如何組裝input和output。從上面的代碼,咱們能夠得出.net
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, 在Composer tab中,貼入咱們的Request.
點擊execute之後,到Inspectors tab裏面,查看response:
接下來,咱們使用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>