java Webservice(一)HttpClient远程调用

我们将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
拳头是最基本的一重武器,也是最重要的,好比练武之人必须先扎稳马步。

java 代码
 
  1. HttpClient httpclient=new HttpClient();//创建一个客户端,类似打开一个浏览器  
  2. GetMethod getMethod=new GetMethod("http://www.blablabla.com");//创建一个get方法,类似在浏览器地址栏中输入一个地址  
  3. int statusCode=httpclient.executeMethod(getMethod);//回车——出拳!  
  4. System.out.println("response=" + getMethod.getResponseBodyAsString());//察看拳头命中情况,可以获得的东西还有很多,比如head, cookies等等  
  5. getMethod.releaseConnection();//释放,记得收拳哦  



2.孔雀翎之支持https

如何支持https?

java 代码
 
  1. static{  
  2.     Protocol easyhttps = new Protocol("https"new EasySSLProtocolSocketFactory(), 443);  
  3.     Protocol.registerProtocol("https", easyhttps);  
  4. }  


在执行具体的http method之前,暗中将https协议注册一把,如孔雀翎暗藏玄机,毙敌于无形。记住,官方的binary发行版本没有ssl的contribute包,方法一是下载源代码版本来打造你的孔雀翎。

3.多情环之cookies
常道人老多情,其实是记忆太多,所以情之所至,正如cookies甜心,无论你走到那,总把你牵挂:

java 代码
 
  1. HttpClient httpclient=new HttpClient();  
  2. httpclient.getParams().setCookiePolicy(CookiePolicy.RFC_2109);//RFC_2109是支持较普遍的一个,还有其他cookie协议  
  3. HttpState initialState = new HttpState();  
  4. Cookie cookie=new Cookie();  
  5. cookie.setDomain("www.balblabla.com");  
  6. cookie.setPath("/");  
  7. cookie.setName("多情环");  
  8. cookie.setValue("多情即无情");  
  9. initialState.addCookie(cookie);  
  10. httpclient.setState(initialState);  
  11. ...  



4.离别钩之解构cookies

多情环的反面即离别钩,钩出,敌之身体某个部件即要与身体别离,端的是无情:

java 代码
 
  1. ...//执行了某些get/post方法后  
  2. Cookie[] cookies = httpclient.getState().getCookies();  
  3. System.out.println("Present cookies: ");  
  4. for (int i = 0; i < cookies.length; i++) {//循环结构零部件  
  5.     System.out.println(" - " + cookies[i].toExternalForm());  
  6.     System.out.println(" - domain=" + cookies[i].getDomain());  
  7.     System.out.println(" - path=" + cookies[i].getPath());  
  8.     ...            
  9. }  



5.霸王抢之post参数
枪,长兵器之王,诸多名将均使一杆或金或银命名的名枪,比如岳飞。post方法在提交参数对时,犹如灵蛇出洞:

java 代码
 
  1. PostMethod postMethod = new PostMethod("http://www.saybot.com/postme");  
  2. NameValuePair[] postData = new NameValuePair[2];  
  3. postData[0] = new NameValuePair("武器""枪");  
  4. postData[1] = new NameValuePair("什么枪""神枪");  
  5. postMethod.addParameters(postData);  
  6. ...//出枪吧  



6.七星碧玉刀之支持代理(proxy)

代理,非常重要,尤其在局域网横行的年头,没有代理,你在公司上不了QQ,没有代理,google不了网页快照,代理之威,可比七星碧玉刀,无刀,在局域网和开发当中,一切白搭:

java 代码
 
  1. HttpClient httpclient=new HttpClient();  
  2. httpClient.getHostConfiguration().setProxy("192.168.0.1"9527);  
  3. httpClient.getParams().setAuthenticationPreemptive(true);//重要!!!告诉httpclient,使用抢先认证,否则你会收到“你没有资格”的恶果  
  4. /* 
  5.   这一步也至关重要,MyProxyCredentialsProvider实现了org.apache.commons.httpclient.auth.CredentialsProvider接口, 
  6.   返回代理的credential(username/password)*/  
  7. httpClient.getParams().setParameter(CredentialsProvider.PROVIDER, new MyProxyCredentialsProvider());  
  8. httpClient.getState().setProxyCredentials(  
  9.     new AuthScope("192.168.0.1",  
  10.         AuthScope.ANY_PORT, //任意端口哦,可要小心  
  11.         AuthScope.ANY_REALM),//任意域哦,可要小心  
  12. new UsernamePasswordCredentials("username",//proxy的用户名  
  13.                         "password"));//proxy的密码  


...

原文地址:https://www.cnblogs.com/ilinuxer/p/4878746.html