簡介 ? ? ??
? ? ? ?WebService是一種服務的提供方式,通過WebService,不同應用間相互間調用變的很方便,網絡上有很多常用的WebService服務,如:http://developer.51cto.com/art/200908/147125.htm,不同的語言平臺對WebService都有實現,Java的WebService實現,比較流行的有Axis2、Jaxws,本文介紹的是Axis2。
Axis2下載和部署
? ? ? ?Axis2是Apache開發的一個開源項目,再次感嘆Apache的偉大!
? ? ? ?下載地址:
? ? ? ?http://mirror.bit.edu.cn/apache//axis/axis2/java/core/1.6.2/axis2-1.6.2-war.zip
? ? ? ?將其內axis2.war解壓到<Tomcat安裝目錄>/webapps下,啟動Tomcat,war包會自動解壓,
? ? ? ?訪問http://localhost:8080/axis2/,如果看到歡迎主頁,則說明部署成功。
配置Axis2
? ? ? ?<Tomcat安裝目錄>/webapps/axis2/WEB-INF/conf/axis2.xml,配置其內兩個屬性,以便調試。
?
- <parameter?name="hotdeployment">true</parameter><!--?開啟熱部署,不需要重啟即可部署服務?-->??
- <parameter?name="hotupdate">true</parameter><!--?開啟熱更新,不需要重啟即可更新服務?-->??
?
編寫服務
? ? ? ?所謂服務就是編寫一個類,寫一些方法,方法返回數據,WebService客戶端獲取數據。
- public?class?HelloService?{??
- ??
- ????public?String?sayHello()?{??
- ????????return?"hello";??
- ????}??
- ??????
- }??
0配置POJO發布服務
? ? ? ?服務類創建好后,我們需要發布到服務器上,將HelloService.class放到<Tomcat安裝目錄>/webapps/axis2/WEB-INF/pojo下,pojo沒有需要創建。
? ? ? ?至此,我們已經成功的創建了一個WebService服務了,so easy!
? ? ? ?再次訪問http://localhost:8080/axis2/,點擊Services,可以發現可用services中多了一個HelloService,其內有一個可用操作sayHello,說明發布成功。
?
- HelloService??
- ??
- Service?Description?:?No?description?available?for?this?service??
- ??
- Service?EPR?:?http://localhost:8080/axis2/services/HelloService??
- ??
- Service?Status?:?Active??
- ??
- ??
- Available?Operations??
- sayHello??
? ? ? ?訪問http://localhost:8080/axis2/services/HelloService,頁面輸出正是我們的返回值。
?
?
- <ns:sayHelloResponse?xmlns:ns="http://ws.apache.org/axis2">??
- <return>hello</return>??
- </ns:sayHelloResponse>??
? ? ? ?這里有兩點需要注意:
?
? ? ? ?- POJO發布的類不能放在包里,既不能使用package關鍵字;
? ? ? ?- 默認的發布目錄是pojo,可以在<Tomcat安裝目錄>/webapps/axis2/WEB-INF/conf/axis2.xml中增加目錄,
?
- <deployer?extension=".class"?directory="<要增加的目錄名稱>"?class="org.apache.axis2.deployment.POJODeployer"?/>??
? ? ? ? ?要注意多個目錄見WebService要唯一,否則會重名,重名后,先部署的會成功,后部署的會報錯。
services.xml配置文件發布服務
? ? ? ?雖然POJO的方式不需要配置文件,但是其服務類不能放在包內,顯然是不符合我們日常開發的,Axis2也允許帶包的類發布WebService,如果不允許,估計就沒人用了。
? ? ? ?首先寫一個較復雜的服務類,多個方法,帶參數,有返回值的。
?
- package?webservice.test;??
- ??
- /**?
- ?*?計算器運算?
- ?*??
- ?*?@author?gaoshuang?
- ?*/??
- public?class?CalculateService?{??
- ??
- ????//?加法??
- ????public?float?plus(float?x,?float?y)?{??
- ????????return?x?+?y;??
- ????}??
- ??
- ????//?減法??
- ????public?float?minus(float?x,?float?y)?{??
- ????????return?x?-?y;??
- ????}??
- ??
- ????//?乘法??
- ????public?float?multiply(float?x,?float?y)?{??
- ????????return?x?*?y;??
- ????}??
- ??
- ????//?除法??
- ????public?float?divide(float?x,?float?y)?{??
- ????????if?(y?!=?0)??
- ????????????return?x?/?y;??
- ????????else??
- ????????????return?-1;??
- ????}??
- }??
? ? ? ?然后編寫services.xml,該文件需要放在META-INF文件夾下。
?
?
- <?xml?version="1.0"?encoding="UTF-8"?>??
- <!--?服務名稱?-->??
- <service?name="CalculateService">??
- ????<!--?服務描述?-->??
- ????<description>??
- ????????加減乘除計算服務??
- ????</description>??
- ????<!--?設置服務類?-->??
- ????<parameter?name="ServiceClass">??
- ????????com.runqianapp.webservice.test.CalculateService??
- ????</parameter>??
- ????<!--?方法?-->??
- ????<operation?name="plus">??
- ????????<!--?方法處理器,RPCMessageReceiver為帶返回值的處理器,??
- ?????????????????????RPCInOnlyMessageReceiver為不帶返回值的處理器?-->??
- ????????<messageReceiver?mep="http://www.w3.org/2004/08/wsdl/in-out"??
- ????????????class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"?/>??
- ????</operation>??
- ????<operation?name="minus">??
- ????????<messageReceiver?mep="http://www.w3.org/2004/08/wsdl/in-out"??
- ????????????class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"?/>??
- ????</operation>??
- ????<operation?name="multiply">??
- ????????<messageReceiver?mep="http://www.w3.org/2004/08/wsdl/in-out"??
- ????????????class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"?/>??
- ????</operation>??
- ????<operation?name="divide">??
- ????????<messageReceiver?mep="http://www.w3.org/2004/08/wsdl/in-out"??
- ????????????class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"?/>??
- ????</operation>??
- </service>??
?
? ? ? ?最后將這兩個文件打成jar包,不論用工具還是手動打,打的都是最外層的文件夾。
? ? ? ?
? ? ? ?我打的名字是server.jar,更改后綴為aar,所以最后是server.aar,Axis2建議使用aar發布WebService,
? ? ? ?將server.aar放到<Tomcat安裝目錄>/webapps/axis2/WEB-INF/services下,訪問http://localhost:8080/axis2/services/listServices,
? ? ? ?多出了一個CalculateService,說明發布成功。
?
- CalculateService??
- ??
- Service?Description?:?CalculateService??
- ??
- Service?EPR?:?http://localhost:8080/axis2/services/CalculateService??
- ??
- Service?Status?:?Active??
- ??
- ??
- Available?Operations??
- divide??
- plus??
- minus??
- multiply??
? ? ? ?分別訪問
?
? ? ? ?http://localhost:8080/axis2/services/CalculateService/plus?x=1&y=2
? ? ? ?http://localhost:8080/axis2/services/CalculateService/divide?x=1&y=2
? ? ? ?http://localhost:8080/axis2/services/CalculateService/minus?x=1&y=2
? ? ? ?http://localhost:8080/axis2/services/CalculateService/multiply?x=1&y=2
? ? ? ?也可以發布多個WebService,可以使用serviceGroup標簽。
?
- <serviceGroup>??
- <service?name="myService1">??
- ????...??
- </service>??
- <service?name="myService2">??
- ????...??
- </service>??
- </serviceGroup>??
客戶端實現
?
? ? ? ?以上介紹的都是WebService服務創建及發布,那么有了一個WebService服務后,我們如何調用呢?只在瀏覽器上訪問是沒有意義的。
? ? ? ?下載Axis2客戶端壓縮包:http://mirror.esocc.com/apache//axis/axis2/java/core/1.6.2/axis2-1.6.2-bin.zip,并解壓。
? ? ? ?新建工程WebServiceClientTest,將<Axis2客戶端安裝目錄>/lib下所有jar包添加到工程中;
? ? ? ?編寫客戶端代碼;
?
- package?webservice.client.test;??
- ??
- 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?Client1?{??
- ??
- ????/**?
- ?????*?@param?args?
- ?????*?@throws?AxisFault?
- ?????*/??
- ????public?static?void?main(String[]?args)?throws?AxisFault?{??
- ????????//?使用RPC方式調用WebService??
- ????????RPCServiceClient?serviceClient?=?new?RPCServiceClient();??
- ????????Options?options?=?serviceClient.getOptions();??
- ????????//?指定調用WebService的URL??
- ????????EndpointReference?targetEPR?=?new?EndpointReference(??
- ????????????????"http://localhost:8080/axis2/services/CalculateService");??
- ????????options.setTo(targetEPR);??
- ????????//?調用方法的參數值??
- ????????Object[]?entryArgs?=?new?Object[]?{1,?2};??
- ????????//?調用方法返回值的數據類型的Class對象??
- ????????Class[]?classes?=?new?Class[]?{?float.class?};??
- ????????//?調用方法名及WSDL文件的命名空間??
- ????????//?命名空間是http://localhost:8080/axis2/services/CalculateService?wsdl中wsdl:definitions標簽targetNamespace屬性??
- ????????QName?opName?=?new?QName("http://test.webservice",?"plus");??
- ????????//?執行方法獲取返回值??
- ????????//?沒有返回值的方法使用serviceClient.invokeRobust(opName,?entryArgs)??
- ????????Object?result?=?serviceClient.invokeBlocking(opName,?entryArgs,?classes)[0];??
- ????????System.out.println(result);??
- ????????//?out:?3.0??
- ????}??
- ??
- }??
? ? ? ?以上是實現了一個簡單的WebSerivce客戶端,調用CalculateService中的plus方法,由代碼可見,這種調用方式比較雜亂,代碼不太友好。
?
wsdl2java簡化客戶端
? ? ? ?<Axis2客戶端安裝目錄>/bin目錄,其內有兩個bat,wsdl2java.bat和java2wsdl.bat,可以實現WSDL文件和Java之間的互相轉換。
? ? ? ?考慮到我們以后可能經常使用這些命令,設置環境變量,方便以后調用。在系統變量中加入AXIS2_HOME=<Axis2客戶端安裝目錄>,path中追加;%AXIS2_HOME%\bin。
? ? ? ?啟動命令提示符,進入WebServiceTestClient所在目錄,運行
?
- wsdl2java?-uri?http://localhost:8080/axis2/services/CalculateService?wsdl?-p?webservice.client.test?-s??
? ? ? ?參數說明:uri - wsdl文件路徑,網絡路徑或本地路徑,p - 打包,這里和上一個客戶端實現類打在了一個包里,wsdl2java有很多參數,詳細可以運行該命令去查看。
?
? ? ? ?執行后,如果沒有報錯,說明運行成功,刷新項目,該包下多出了一個CalculateServiceStub類,里面的代碼極其復雜,還亂呼呼的,這我們不用管,調用該類。
?
- package?webservice.client.test;??
- ??
- import?java.rmi.RemoteException;??
- ??
- import?webservice.client.test.CalculateServiceStub.Plus;??
- ??
- public?class?Client2?{??
- ??
- ????/**?
- ?????*?@param?args?
- ?????*?@throws?RemoteException??
- ?????*/??
- ????public?static?void?main(String[]?args)?throws?RemoteException?{??
- ????????CalculateServiceStub?stub?=?new?CalculateServiceStub();??
- ????????Plus?plus?=?new?Plus();??
- ????????plus.setX(1);??
- ????????plus.setY(2);??
- ????????float?result?=?stub.plus(plus).get_return();//?返回值自動轉型,這也是強大之處??
- ????????System.out.println(result);??
- ????}??
- ??
- }??
?
? ? ? ?如此做的好處就是調用時不需要在去查看WSDL,和正常使用一個類一樣,對WebService的封裝都由wsdl2java自動生成,代碼更優雅、簡潔。
利用wsdl2java輕松使用第三方WebService服務
? ? ? ?有了wsdl2java,已知一個WSDL文件我們就可以輕松的生成WebService客戶端供我們調用,給我們服務。文章開頭給出的鏈接包含了一些第三方服務,有一個服務是生成隨機個數中文,WSDL:http://www.webxml.com.cn/WebServices/RandomFontsWebService.asmx?wsdl,同樣,啟動命令提示符,進入項目路徑,執行
?
- wsdl2java?-uri?http://www.webxml.com.cn/WebServices/RandomFontsWebService.asmx?wsdl?-p?webservice.client.test?-s??
? ? ? ?調用該類
?
?
- package?webservice.client.test;??
- ??
- import?java.rmi.RemoteException;??
- ??
- import?webservice.client.test.RandomFontsWebServiceStub.ArrayOfString;??
- import?webservice.client.test.RandomFontsWebServiceStub.GetChineseFonts;??
- ??
- public?class?ThirdClient?{??
- ??
- ????/**?
- ?????*?@param?args?
- ?????*?@throws?RemoteException??
- ?????*/??
- ????public?static?void?main(String[]?args)?throws?RemoteException?{??
- ????????RandomFontsWebServiceStub?stub?=?new?RandomFontsWebServiceStub();??
- ????????GetChineseFonts?getChineseFonts?=?new?GetChineseFonts();??
- ????????getChineseFonts.setByFontsLength(10);//?免費使用有限制,最多8個??
- ????????ArrayOfString?result?=?stub.getChineseFonts(getChineseFonts).getGetChineseFontsResult();??
- ????????for(String?str?:?result.getString())?{??
- ????????????System.out.println(str);??
- ????????}??
- ????}??
- ??
- } ?