我們將Web Service發布在Tomcat或者其他應用服務器上后,有很多方法可以調用該Web Service,常用的有兩種:
1、通過瀏覽器HTTP調用,返回規范的XML文件內容
2、通過客戶端程序調用,返回結果可自定義格式
接下來,我利用Eclipse作為開發工具,演示一個Httpclient調用WebService的簡單示例
第一種調用見我的另一篇博文:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/10/3071584.html
步驟如下:
准備工作:用到的jar包有: 下載鏈接(http://download.csdn.net/detail/lanxuezaipiao/5354480)
第一步:新建Java Project,項目名稱為HttpCallWebService
第二步:將所需jar包導入到庫中
第三步:編寫調用class,這里有兩種方式調用,即GET方式和POST方式,由於POST方式較安全,故這里采用POST方式調用;請求數據的構造也有兩種方式:靜態和動態構造,下面分別介紹這兩種方式:
注:這里以E郵寶開放的webservice接口為例調用其中一個API函數,而E郵寶的webservice基於SOAP,故請求數據為SOAP格式,大家可根據自己情況進行修改
靜態構造請求數據:
1 package com.http; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 7 import org.apache.commons.httpclient.HttpClient; 8 import org.apache.commons.httpclient.HttpException; 9 import org.apache.commons.httpclient.methods.InputStreamRequestEntity; 10 import org.apache.commons.httpclient.methods.PostMethod; 11 import org.apache.commons.httpclient.methods.RequestEntity; 12 13 public class StaticHttpclientCall { 14 15 /** 16 * @param args 17 * @throws IOException 18 * @throws HttpException 19 */ 20 public static void main(String[] args) throws HttpException, IOException { 21 // TODO Auto-generated method stub 22 23 String soapRequestData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 24 + "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" 25 + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" 26 + " xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">" 27 + " <soap12:Body>" 28 + " <GetAPACShippingPackage xmlns=\"http://shippingapi.ebay.cn/\">" 29 + " <GetAPACShippingPackageRequest>" 30 + " <TrackCode>123</TrackCode>" 31 + " <Version>123</Version>" 32 + " <APIDevUserID>123</APIDevUserID>" 33 + " <APIPassword>123</APIPassword>" 34 + " <APISellerUserID>123</APISellerUserID>" 35 + " <MessageID>123</MessageID>" 36 + " </GetAPACShippingPackageRequest>" 37 + " </GetAPACShippingPackage>" + "</soap12:Body>" 38 + " </soap12:Envelope>"; 39 40 System.out.println(soapRequestData); 41 42 PostMethod postMethod = new PostMethod( 43 "http://epacketws.pushauction.net/v3/orderservice.asmx?wsdl"); 44 45 // 然后把Soap請求數據添加到PostMethod中 46 byte[] b = soapRequestData.getBytes("utf-8"); 47 InputStream is = new ByteArrayInputStream(b, 0, b.length); 48 RequestEntity re = new InputStreamRequestEntity(is, b.length, 49 "application/soap+xml; charset=utf-8"); 50 postMethod.setRequestEntity(re); 51 52 // 最后生成一個HttpClient對象,並發出postMethod請求 53 HttpClient httpClient = new HttpClient(); 54 int statusCode = httpClient.executeMethod(postMethod); 55 if(statusCode == 200) { 56 System.out.println("調用成功!"); 57 String soapResponseData = postMethod.getResponseBodyAsString(); 58 System.out.println(soapResponseData); 59 } 60 else { 61 System.out.println("調用失敗!錯誤碼:" + statusCode); 62 } 63 64 } 65 66 }
動態構造數據:
1 package com.http; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.InputStream; 5 import java.util.HashMap; 6 import java.util.Map; 7 import java.util.Set; 8 9 import org.apache.commons.httpclient.HttpClient; 10 import org.apache.commons.httpclient.methods.InputStreamRequestEntity; 11 import org.apache.commons.httpclient.methods.PostMethod; 12 import org.apache.commons.httpclient.methods.RequestEntity; 13 14 // 動態構造調用串,靈活性更大 15 public class DynamicHttpclientCall { 16 17 private String namespace; 18 private String methodName; 19 private String wsdlLocation; 20 private String soapResponseData; 21 22 public DynamicHttpclientCall(String namespace, String methodName, 23 String wsdlLocation) { 24 25 this.namespace = namespace; 26 this.methodName = methodName; 27 this.wsdlLocation = wsdlLocation; 28 } 29 30 private int invoke(Map<String, String> patameterMap) throws Exception { 31 PostMethod postMethod = new PostMethod(wsdlLocation); 32 String soapRequestData = buildRequestData(patameterMap); 33 34 byte[] bytes = soapRequestData.getBytes("utf-8"); 35 InputStream inputStream = new ByteArrayInputStream(bytes, 0, 36 bytes.length); 37 RequestEntity requestEntity = new InputStreamRequestEntity(inputStream, 38 bytes.length, "application/soap+xml; charset=utf-8"); 39 postMethod.setRequestEntity(requestEntity); 40 41 HttpClient httpClient = new HttpClient(); 42 int statusCode = httpClient.executeMethod(postMethod); 43 soapResponseData = postMethod.getResponseBodyAsString(); 44 45 return statusCode; 46 } 47 48 private String buildRequestData(Map<String, String> patameterMap) { 49 StringBuffer soapRequestData = new StringBuffer(); 50 soapRequestData.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 51 soapRequestData 52 .append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" 53 + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" 54 + " xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"); 55 soapRequestData.append("<soap12:Body>"); 56 soapRequestData.append("<" + methodName + " xmlns=\"" + namespace 57 + "\">"); 58 soapRequestData.append("<" + methodName + "Request>"); 59 60 Set<String> nameSet = patameterMap.keySet(); 61 for (String name : nameSet) { 62 soapRequestData.append("<" + name + ">" + patameterMap.get(name) 63 + "</" + name + ">"); 64 } 65 66 soapRequestData.append("</" + methodName + "Request>"); 67 soapRequestData.append("</" + methodName + ">"); 68 soapRequestData.append("</soap12:Body>"); 69 soapRequestData.append("</soap12:Envelope>"); 70 71 return soapRequestData.toString(); 72 } 73 74 /** 75 * @param args 76 * @throws Exception 77 */ 78 public static void main(String[] args) throws Exception { 79 // TODO Auto-generated method stub 80 81 DynamicHttpclientCall dynamicHttpclientCall = new DynamicHttpclientCall( 82 "http://shippingapi.ebay.cn/", "GetAPACShippingPackage", 83 "http://epacketws.pushauction.net/v3/orderservice.asmx?wsdl"); 84 85 Map<String, String> patameterMap = new HashMap<String, String>(); 86 87 patameterMap.put("TrackCode", "123"); 88 patameterMap.put("Version", "123"); 89 patameterMap.put("APIDevUserID", "123"); 90 patameterMap.put("APIPassword", "123"); 91 patameterMap.put("APISellerUserID", "123"); 92 patameterMap.put("MessageID", "123"); 93 patameterMap.put("TrackCode", "123"); 94 95 String soapRequestData = dynamicHttpclientCall.buildRequestData(patameterMap); 96 System.out.println(soapRequestData); 97 98 int statusCode = dynamicHttpclientCall.invoke(patameterMap); 99 if(statusCode == 200) { 100 System.out.println("調用成功!"); 101 System.out.println(dynamicHttpclientCall.soapResponseData); 102 } 103 else { 104 System.out.println("調用失敗!錯誤碼:" + statusCode); 105 } 106 107 } 108 109 }
最終運行結果:
package httpclient;
import java.io.IOException;
import java.net.URLEncoder;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public class HttpClientTest {
public static void main(String[] args) throws Exception{
String url = "/webservices/DomesticAirline.asmx/getDomesticAirlinesTime";
String host = "www.webxml.com.cn";
String param = "startCity="+URLEncoder.encode("杭州", "utf-8")+"&lastCity=&theDate=&userID=";
HttpClient httpClient = new HttpClient();
httpClient.getHostConfiguration().setHost(host, 80, "http");
HttpMethod method = getMethod(url, param);
//HttpMethod method = postMethod(url);
httpClient.executeMethod(method);
String response = method.getResponseBodyAsString();
//String response = new String(method.getResponseBodyAsString().getBytes("ISO-8859-1"));
System.out.println(response);
}
private static HttpMethod getMethod(String url,String param) throws IOException{
GetMethod get = new GetMethod(url+"?"+param);
get.releaseConnection();
return get;
}
private static HttpMethod postMethod(String url) throws IOException{
PostMethod post = new PostMethod(url);
post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gbk");
NameValuePair[] param = { new NameValuePair("startCity","杭州"),
new NameValuePair("lastCity","沈陽"),
new NameValuePair("userID",""),
new NameValuePair("theDate","") } ;
post.setRequestBody(param);
post.releaseConnection();
return post;
}
}
如果PostMethod提交的是中文字符,需要加上相應的編碼格式: post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gbk");
如果GetMethod提交的參數有中文字符,需要先轉換成utf-8格式: URLEncoder.encode("杭州", "utf-8");
1.拳頭之Get/Post
拳頭是最基本的一重武器,也是最重要的,好比練武之人必須先扎穩馬步。
- HttpClient httpclient=new HttpClient();//創建一個客戶端,類似打開一個瀏覽器
- GetMethod getMethod=new GetMethod("http://www.blablabla.com");//創建一個get方法,類似在瀏覽器地址欄中輸入一個地址
- int statusCode=httpclient.executeMethod(getMethod);//回車——出拳!
- System.out.println("response=" + getMethod.getResponseBodyAsString());//察看拳頭命中情況,可以獲得的東西還有很多,比如head, cookies等等
- getMethod.releaseConnection();//釋放,記得收拳哦
2.孔雀翎之支持https
如何支持https?
- static{
- Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
- Protocol.registerProtocol("https", easyhttps);
- }
在執行具體的http method之前,暗中將https協議注冊一把,如孔雀翎暗藏玄機,斃敵於無形。記住,官方的binary發行版本沒有ssl的contribute包,方法一是下載源代碼版本來打造你的孔雀翎。
3.多情環之cookies
常道人老多情,其實是記憶太多,所以情之所至,正如cookies甜心,無論你走到那,總把你牽掛:
- HttpClient httpclient=new HttpClient();
- httpclient.getParams().setCookiePolicy(CookiePolicy.RFC_2109);//RFC_2109是支持較普遍的一個,還有其他cookie協議
- HttpState initialState = new HttpState();
- Cookie cookie=new Cookie();
- cookie.setDomain("www.balblabla.com");
- cookie.setPath("/");
- cookie.setName("多情環");
- cookie.setValue("多情即無情");
- initialState.addCookie(cookie);
- httpclient.setState(initialState);
- ...
4.離別鈎之解構cookies
多情環的反面即離別鈎,鈎出,敵之身體某個部件即要與身體別離,端的是無情:
- ...//執行了某些get/post方法后
- Cookie[] cookies = httpclient.getState().getCookies();
- System.out.println("Present cookies: ");
- for (int i = 0; i < cookies.length; i++) {//循環結構零部件
- System.out.println(" - " + cookies[i].toExternalForm());
- System.out.println(" - domain=" + cookies[i].getDomain());
- System.out.println(" - path=" + cookies[i].getPath());
- ...
- }
5.霸王搶之post參數
槍,長兵器之王,諸多名將均使一桿或金或銀命名的名槍,比如岳飛。post方法在提交參數對時,猶如靈蛇出洞:
- PostMethod postMethod = new PostMethod("http://www.saybot.com/postme");
- NameValuePair[] postData = new NameValuePair[2];
- postData[0] = new NameValuePair("武器", "槍");
- postData[1] = new NameValuePair("什么槍", "神槍");
- postMethod.addParameters(postData);
- ...//出槍吧
6.七星碧玉刀之支持代理(proxy)
代理,非常重要,尤其在局域網橫行的年頭,沒有代理,你在公司上不了QQ,沒有代理,google不了網頁快照,代理之威,可比七星碧玉刀,無刀,在局域網和開發當中,一切白搭:
- HttpClient httpclient=new HttpClient();
- httpClient.getHostConfiguration().setProxy("192.168.0.1", 9527);
- httpClient.getParams().setAuthenticationPreemptive(true);//重要!!!告訴httpclient,使用搶先認證,否則你會收到“你沒有資格”的惡果
- /*
- 這一步也至關重要,MyProxyCredentialsProvider實現了org.apache.commons.httpclient.auth.CredentialsProvider接口,
- 返回代理的credential(username/password)*/
- httpClient.getParams().setParameter(CredentialsProvider.PROVIDER, new MyProxyCredentialsProvider());
- httpClient.getState().setProxyCredentials(
- new AuthScope("192.168.0.1",
- AuthScope.ANY_PORT, //任意端口哦,可要小心
- AuthScope.ANY_REALM),//任意域哦,可要小心
- new UsernamePasswordCredentials("username",//proxy的用戶名
- "password"));//proxy的密碼
...