以前一直把Web Services说在嘴边,都没亲自去试验下,或者都是通过别人的API去调用,没有从底层去实验,今天病好很多,下午也闲来无事,便把这个一直留在心里的任务给完成了,以满足自己。
Web Services的原理我就不仔细说了,可以参考一本《Web Services技术、架构和应用》,书虽有点厚,但很经典。
本文调用http://www.webxml.com.cn/zh_cn/index.aspx提供的Web Services,该网站提供了几种WEB服务。本文以手机号码归属地查询为例,介绍调用Web Services的方法。
首先在http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?op=getMobileCodeInfo,我们便可看到该方法的参数传递形式。
SOAP 1.1 以下是 SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。 POST /WebServices/MobileCodeWS.asmx HTTP/1.1 Host: webservice.webxml.com.cn Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://WebXml.com.cn/getMobileCodeInfo" <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> <mobileCode>string</mobileCode> <userID>string</userID> </getMobileCodeInfo> </soap:Body> </soap:Envelope> HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>string</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap:Body> </soap:Envelope> SOAP 1.2 以下是 SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。 POST /WebServices/MobileCodeWS.asmx HTTP/1.1 Host: webservice.webxml.com.cn 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> <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> <mobileCode>string</mobileCode> <userID>string</userID> </getMobileCodeInfo> </soap12:Body> </soap12:Envelope> HTTP/1.1 200 OK 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> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>string</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap12:Body> </soap12:Envelope>
本文以socket为例子,通过底层方式调用Web Services,把上述的协议描述输成代码,如下:
String strHeader = "POST /WebServices/MobileCodeWS.asmx HTTP/1.1/r/n" + "Host: webservice.webxml.com.cn/r/n" + "Content-Type: text/xml; charset=utf-8/r/n" + "Content-Length: $Length/r/n" + "SOAPAction: /"http://WebXml.com.cn/getMobileCodeInfo/"/r/n/r/n"; String strBody = "<?xml version=/"1.0/" encoding=/"utf-8/"?>/r/n" + "<soap:Envelope xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//">/r/n" + "<soap:Body>/r/n" + "<getMobileCodeInfo xmlns=/"http://WebXml.com.cn//">/r/n" + "<mobileCode>$MobileNo</mobileCode>/r/n" + "<userID>$UserID</userID>/r/n" + "</getMobileCodeInfo>/r/n" + "</soap:Body>/r/n" + "</soap:Envelope>/r/n";
在这里要注意,代码的形式,协议Header和协议Body要区分清楚,否则会出现调用HTTP400或者HTTP500错误。
使用Socket完整代码如下:
import java.io.BufferedInputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; public class JavaTest { public static void main(String[] argv) { String strHeader = "POST /WebServices/MobileCodeWS.asmx HTTP/1.1/r/n" + "Host: webservice.webxml.com.cn/r/n" + "Content-Type: text/xml; charset=utf-8/r/n" + "Content-Length: $Length/r/n" + "SOAPAction: /"http://WebXml.com.cn/getMobileCodeInfo/"/r/n/r/n"; String strBody = "<?xml version=/"1.0/" encoding=/"utf-8/"?>/r/n" + "<soap:Envelope xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//">/r/n" + "<soap:Body>/r/n" + "<getMobileCodeInfo xmlns=/"http://WebXml.com.cn//">/r/n" + "<mobileCode>$MobileNo</mobileCode>/r/n" + "<userID>$UserID</userID>/r/n" + "</getMobileCodeInfo>/r/n" + "</soap:Body>/r/n" + "</soap:Envelope>/r/n"; String path = "webservice.webxml.com.cn";// try { InetAddress addr = InetAddress.getByName(path); Socket socket = new Socket(addr, 80); OutputStream os = socket.getOutputStream(); InputStream is = socket.getInputStream(); strBody = strBody.replaceAll("//$MobileNo", "15013055281"); strBody = strBody.replaceAll("//$UserID", ""); byte[] bodyBytes = strBody.getBytes(); strHeader = strHeader.replaceAll("//$Length", "" + bodyBytes.length); String httpSend = strHeader + strBody; System.out.println(httpSend); os.write(httpSend.getBytes()); os.flush(); byte[] recvBytes = new byte[4096]; int length = 0; BufferedInputStream bis = new BufferedInputStream(is); while((length = bis.read(recvBytes) ) != -1){ String recvStr = new String(recvBytes, "UTF-8"); System.out.println(recvStr); } } catch (Exception e) { e.printStackTrace(); } } }
使用HttpURLConnection关键代码代码如下(原理都一样,只不过少写了点东西而已):
String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"; try { strBody = strBody.replaceAll("//$MobileNo", "15013055288"); strBody = strBody.replaceAll("//$UserID", ""); byte[] bodyBytes = strBody.getBytes(); strHeader = strHeader .replaceAll("//$Length", "" + bodyBytes.length); String httpSend = strBody; System.out.println(httpSend); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setConnectTimeout(5 * 1000); conn.setRequestProperty("Content-Type","application/soap+xml; charset=utf-8"); conn.setRequestProperty("Content-Length", String.valueOf(bodyBytes.length)); OutputStream os = conn.getOutputStream(); os.write(bodyBytes); os.flush(); InputStream is = conn.getInputStream(); byte[] recvBytes = new byte[4096]; int length = 0; BufferedInputStream bis = new BufferedInputStream(is); while((length = bis.read(recvBytes) ) != -1){ String recvStr = new String(recvBytes, "UTF-8"); System.out.println(recvStr); } } catch (Exception e) { e.printStackTrace(); }
得到调用结果如下:
HTTP/1.1 200 OK Date: Thu, 10 Feb 2011 14:35:02 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 434 <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>15013055288:广东 广州 广东移动全球通卡 </getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap:Body> </soap:Envelope>
以上便是从底层调用Web Services的方法。
版权所有,转载请注明出处