1. 程式人生 > >Java動態呼叫複雜引數的WebService【精選彙總篇一】

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