Java動態呼叫複雜引數的WebService【精選彙總篇一】
Java如何動態的呼叫WebService?
一定時動態、動態、動態...不是動態就不是想要的解決方案。(本篇正在更新中..可以關注後,持續探討)
一.方案彙總
網上查詢的很多資料,零零散散沒有找到一個比較滿意的方案,特地彙總一下解決方案。
目前解決方案暫定為3種
1.利用cxf動態呼叫webservice
2.利用axis2的RPC方式呼叫webservice
3.利用HttpClient呼叫webservice
二.問題剖析
1.利用cxf動態呼叫webservice
查詢資料後,首先說下cxf的解決方案。
1.1簡單型別的動態呼叫如下
定義方法WebService方法:
package com.limp.service; import com.limp.domain.OrderInfo; import javax.jws.WebMethod; import javax.jws.WebService; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @intro : * @auth : shinians * @time : 2018/11/21 16:56 * @website: www.shinians.com */ @WebService public interface HelloService { /** * 你好,webservice * @param name * @return */ @WebMethod String sayHello(String name); @WebMethod String sayHello2(String name,String name2); @WebMethod String testMap(HashMap<String,String> param,String name); @WebMethod String testListMap(List<HashMap<String,String>>listMap); /** * 啊 遇到這個問題 就是Webservice不能傳遞Map型別的資料。 webservice可以處理String 基本資料型別,普通POJO、list 陣列。 所以將map進行轉換吧。 * @param mapOrder * @return */ // @WebMethod // String getMapOrder(Map<String,OrderInfo> mapOrder); @WebMethod(action = "process") String getOrder(OrderInfo order); @WebMethod String getOrderList(List<OrderInfo> orders); }
以 String sayHello(String name)為例,呼叫方式如下(動態引數需要自行封裝)。
/** * 簡單型別的呼叫(String): */ public static void SimpleInvoke(){ // 建立動態客戶端 JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient(wsdlUrl); // 需要密碼的情況需要加上使用者名稱和密碼 // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD)); Object[] objects = new Object[0]; try { // invoke("方法名",引數1,引數2,引數3....); objects = client.invoke("sayHello", "張三"); System.out.println("返回資料:" + objects[0]); } catch (java.lang.Exception e) { e.printStackTrace(); } }
呼叫成功返回結果如下
1.2複雜物件形式呼叫
對於簡單型別呼叫網上一搜到處都是解決方案,但是對於複雜物件形式傳參如何解決呢?
以 String getOrder(OrderInfo order);方法為例
測試方法如下:
/**
* 物件傳參
*/
public static void pojoInvoke(){
// 建立動態客戶端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsdlUrl);
Object[] objects = new Object[0];
try {
//通過反射,建立OrderInfo物件,com.limp.service.OrderInfo 這個包名稱必須和webservice的中的order路徑一致
Object order = Thread.currentThread().getContextClassLoader().
loadClass("com.limp.service.OrderInfo").newInstance();
//初始化實體物件
Method m = order.getClass().getMethod("setId", String.class);
Method m1 = order.getClass().getMethod("setMoney", double.class);
Method m2 = order.getClass().getMethod("setOrderNo", String.class);
m.invoke(order, "uuid213-281heq-2131");
m1.invoke(order, 23);
m2.invoke(order, "NO110");
//開始呼叫
objects = client.invoke("getOrder", order);
System.out.println("呼叫物件形式引數返回資料:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
java.lang.NoSuchMethodException: com.limp.service.OrderInfo.setMoney(java.lang.Double) -->將Double.class改成double.class總之時保持一致
這是網上搜到的一個解決方法,然則Thread.currentThread().getContextClassLoader().loadClass(“com.limp.service.OrderInfo") 這個com.limp.service.OrderInfo包路徑你是怎麼知道的呢,如果服務端是在另一個單位,這個路徑你通過什麼方法知道的呢,否則還是不能稱為動態呼叫啊。(其他人的疑問,其實我也是這樣疑問的,總之這還不是徹底的解決方案,算不上動態呀,但是,總歸是能有調通的可能性)
物件呼叫擴充套件篇章如下(同時解決呼叫返回慢的問題)
還是以上面的為例。
參考下面這個兩個例子(抱歉暫時沒弄成功,先用其他方式弄)
http://cxf.apache.org/docs/dynamic-clients.html
https://bbs.csdn.net/topics/390797587
更新出爐,完全解決動態呼叫過程,包含多種情況處理,參考以下博文
博文連結:cxf動態呼叫webservice(引數包含多個形參、List集合、JAVABean物件)
net寫的webservice用cxf呼叫會有問題。如下面連結
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?op=getSupportDataSet
初步解決方案:採用其他的方式呼叫,如httpclient