Java調用Webservice

網上查找資料總結有以下實現方式

1)使用命令生成接口和實體類,如wsimport -p . -keep http://localhost:8080/hello?wsdl,直接調取接口使用,但是生成了一大堆文件

2)xfire,後續版本cxf,個人建議使用,兼容大多數

3)axis,後續版本axis2,調用webservice感覺兼容性差,但是用來發布webservice感覺很方便,axis2本身就是一個web服務,只需要把寫好的.class方法文件往服務路徑裏面一扔一個webservice就對外發布了

4)直接使用http請求,get和post方法都可以,就是自己封裝成envelop的xml格式參數,get方法需要得到輸入流往裏面寫入參數,post方法可以直接將xml參數作爲實體傳參,我使用post方法實現。

下面是我的做法

1)先考慮使用cxf,因爲cxf調用起來真心的簡單。

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>3.1.9</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>3.1.9</version>
</dependency>
下面是調用demo,如果對同一個webservice服務多次調用,可以將client靜態緩存。

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9003/soap?wsdl");
Object[] o=new Object[]{"arg0","arg1"};//入參按照方法的順序填充
try {
    Object[] result = client.invoke("getUser",o);//getUser是方法名,client.invoke("getUser","liu","fang");
    //輸出調用結果
    System.out.println(result[0].getClass());
    System.out.println(result[0].toString());
    System.out.println(JSONObject.fromObject(result[0]).toString());
} catch (Exception e) {
    e.printStackTrace();
}

2)cxf調不通的,一般是C#寫的webservice,1)入參使用了ref這種結構 2)出參解析的時候多了一個實體類的描述,在這種情況我直接用http請求自己解析xml實現。

網上有很多demo

用org.apache.httpcomponents httpcore的HttpWebRequest實現http://www.cnblogs.com/hfliyi/archive/2012/09/16/2687843.html  

用org.apache.httpcomponents httpclient的httpClient實現http://blog.csdn.net/zhengyong15984285623/article/details/50969099,用低版本的httpClient實現http://www.cnblogs.com/chenying99/p/3746797.html

用HttpURLConnection實現 http://blog.csdn.net/bjxyj/article/details/46725899  http://blog.csdn.net/bjxyj

我現在使用httpClient的CloseableHttpClient實現,沒有啓用連接池

public static String doHttpPost(String apiUrl, String content,String contentType) throws Exception{
   CloseableHttpClient httpClient = HttpClients.createDefault();
   String httpStr = null;
   HttpPost httpPost = new HttpPost(apiUrl);
   CloseableHttpResponse response = null;
   try {
      StringEntity stringEntity = new StringEntity(content, "UTF-8");
      stringEntity.setContentEncoding("UTF-8");
      stringEntity.setContentType(contentType);
      httpPost.setEntity(stringEntity);
      response = httpClient.execute(httpPost);
      httpStr = EntityUtils.toString(response.getEntity(), "UTF-8");
   } catch (Exception e) {
      throw e;
   } finally {
      if (response != null) {
         try {
            EntityUtils.consume(response.getEntity());
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
   }
   httpClient.close();
   return httpStr;
}
public static String doPost(String webserviceURL,Object[] objects) throws Exception {
   return doHttpPost(webserviceURL,buildXML(objects),"text/xml;charset=utf-8");
}


public static String buildXML(Object[] objects){
   StringBuilder sb = new StringBuilder("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tns=\"http://tempuri.org/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
sb.append("<soap:Header/>");
sb.append("<soap:Body>");
sb.append("<tns:getUser>");//我實際調用時方法名用objects[0]
sb.append("<arg0>liu</arg0>");//我實際調用時參數1使用objects[1]
sb.append("<arg1>fang</arg1>");//我實際調用時參數2使用objects[2]
sb.append("</tns:getUser>");//我實際調用時使用objects[0]
sb.append("</soap:Body>");
sb.append("</soap:Envelope>");

return sb.toString();
} 注意調通的關鍵是xml參數,你可以使用soapUI工具進行調試

soap是引用信封envelope,參數值固定,soap可以修改成其它名字如soapenv,如果改成了soapenv後面的標籤中soap也需要修改

tns後面接的是命名空間,直接訪問?wsdl路徑就可以看到,沒有修改的話默認就是http://tempuri.org/,tns也可以改成其它的名字,如常見的tem,相應的後面的方法和參數標籤中也需要修改。關於入參,一般參數和方法的寫法一致也要加上tns:的前綴,但在我的demo中參數必須是arg0,arg1,arg2這種寫法才能取到值。

一般webservice要寫成這樣,如<tns:getUser><tns:firstname>liufang</tns:firstname><tns:lastname>fang</tns:lastname></tns:getUser>

xsd在本例中可以不用添加


我測試時發佈webservice採用最簡單的方法

public String getUser(String firstname,String lastname){
   return firstname+" "+lastname;
}
public static void main(String[] args) {
   javax.xml.ws.Endpoint.publish("http://localhost:9003/soap", new NativeMethod());
   System.out.println("werbservice publish success");
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章