在上一篇中寫了一個簡單了webservice,實現了一個sayHello功能。那么webservice寫好之后我們如何使用Java程序來調用webservice呢?
一、java調用的webservice的第一種方式:RPC調用AXIS2 webservice
下面這個方法是我抽象出來的一個方法,
import javax.xml.namespace.QName; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; public class Client { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // 調用PublishWebService String wsdlUrl = "http://localhost:8080/DigitalProduct/services/PublishWebService?wsdl";//webservice地址 String method = "updatePublishSysParam"; //調用的那個方法 Object[] param = new Object[] { "AASSDDFF" };//傳遞的參數值 String namespaceUrl1 = "http://service.digitalproduct.tkbs.com";//命名空間 Class[] opReturnType1 = new Class[] { String[].class };//返回值類型 String result = axis2RPCInvoke(wsdlUrl, method, param, namespaceUrl1,opReturnType1); System.out.println(result); } /** * RPC調用AXIS2 webservice * * @param wsdlUrl * 服務地址 如:http://192.168.0.1:2597/aixs2/services/jqservice?wsdl * @param methodName * 方法名 如<xs:element name="Receive"> * @param parameter * 方法參數 如Object[] opArgs = new Object[] { param }; * @param namespaceURI * 命名空間 如 :targetNamespace="http://server.test.com.cn"> * @param returnType * 返回類型 如字符串:Class[] opReturnType = new Class[] { String[].class * }; */ public static String axis2RPCInvoke(String wsdlUrl, String methodName, Object[] parameter, String namespaceURI, Class[] returnType) { Object[] ret = null; RPCServiceClient serviceClient = null; try { /* * 此處RPCServiceClient 對象實例建議定義成類中的static變量 ,否則多次調用會出現連接超時的錯誤。 */ serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); EndpointReference targetEPR = new EndpointReference(wsdlUrl); options.setTo(targetEPR); QName opQName = new QName(namespaceURI, methodName); ret = serviceClient.invokeBlocking(opQName, parameter, returnType); // System.out.println(((String[]) ret[0])[0]); } catch (AxisFault e) { e.printStackTrace(); } return ((String[]) ret[0])[0]; } }
二、使用java調用webservice的第二種方式:使用myeclipse中的axis2插件生成客戶端代碼
new -->others到如下界面:
點next 到如下界面:
現在我們想生成調用webservice的客戶端代碼,首先我們需要生成一個service.wsdl文件,選擇第2個,點next,
在界面里邊點擊add folder 選擇項目--》webroot--》webinf-->classes,輸入好webservice那個類的全名后點擊Test Class Loading ,這時候如果你選擇的路徑是對的,類全名是對的,就可以點next,否則next按鈕式灰色的。如圖:
然后點擊next,這個界面中的內容基本不用修改,有一個service name ,你可以改成你自己取。
繼續點next 在界面中選擇wsdl文件的輸出路徑,選擇第一個,就是輸出到當前的workspace,的某個項目下,選擇第二個,就是輸出到系統文件夾中,例如你可以選擇桌面。
這里我選擇第二個,然后點browse選擇桌面,點finish,會看到桌面上有一個service.wsdl文件。
下面我們就可以根據這個wsdl文件生成客戶端代碼了。
首先建一個java項目,例如取名myclient
new -->others-->
選擇第1個,點next.
在界面中點 browse找到你剛才生成service.wsdl文件。
點next,這個界面不用管,繼續點next
這個時候需要選擇代碼生成的地方,選擇當前工作的workspace,然后選擇剛才新建的myclient如圖:
點finsh,刷新myclient項目會看到src下多了兩個java文件:TestServiceCallbackHandler 和 TestServiceStub
接下來就可以寫java代碼調用了,如下:
import myservice.service.TestServiceStub; public class Test { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub //初始化Sub類 TestServiceStub stub = new TestServiceStub(); //傳遞AxisServiceStub.ShowName對象,相關參數在這邊賦值。 TestServiceStub.SayHello command = new TestServiceStub.SayHello(); command.setName("zhangsan"); //取得返回值 String name = stub.sayHello(command).get_return(); System.out.println(name); } }
如此,第二種方式就寫完了。
公司幾個同事都喜歡第二種。但是,我個人喜歡用第一種。第二種方式如果插件使用熟練的話,很快就可以生產客戶端代碼,然后測試代碼也可以很快寫出來。
注:可能會出現錯誤,根據我的經歷的錯誤經驗,有以下情況:
1.tomcat端口問題,你打開剛才插架自動生成的TestServiceStub 類 ctrl+f查找 http://localhost,查到后看他后面的端口是多少,是不是8080,?好像生成的就是8080,但是我們的tomcat可能被自己修改過,端口可能不是8080,所以這里你要改這個端口。
2.spring的注入問題,如果你寫的webservice是在spring整合的環境下,可能會報錯誤,一般是由 spring注入失敗,導致xxxService類注入失敗。關於這個我下一篇會詳細解釋。
3.一切都正常,打斷點調試看到方法執行成功了、執行完畢了,但是並沒有成功的返回我們要的結果,而是報超時了,這時候,我們需要在TestServiceStub 中加入一行代碼
這行代碼的作用是 規定超時時間 是多長,例如你可以設為10分鍾。_operationClient.getOptions().setTimeOutInMilliSeconds(600000L); //600*1000毫秒(10分鍾
我感覺這樣設置不合理,但是可以解決這個錯誤,讓你的程序運行成功,看到運行成功返回的結果。才有繼續學習的勁頭啊。