前言
進公司實習要對以前的項目進行維修,設計到WebService,接下來對axis2框架發佈web項目開發webservice和接口調用進行展開。因爲是以前的技術,我真的搜了好久。太難了,不過還是要分享出來
axis2的下載安裝
下載地址:http://axis.apache.org/axis2/java/core/download.html
下載這兩個即可
bin包:是安裝包;
war包:用於在tomcat上發佈服務;
service-plugin插件:用於將服務打包成爲後綴名爲.aar的文件;codegen-plugin插件:用來將服務代碼生成wsdl文件以及解析wsdl文件並生成客戶端代碼文件(stub文件)
下載結束後
將之前下載的war包解壓後的axis2.war放到tomcat的webapps目錄下,然後啓動tomcat
在地址欄輸入:http://localhost:8080/axis2/,如下圖表示成功
如何通過axis2發佈WebService
1. 創建新的web工程
以下是創建的步驟,會的同學可以直接跳過。
2. 創建服務類HelloWorld
package com;
public class HelloWorld {
public String getHello(String name) {
return "Hello, " + name + ".";
}
public String getWorld(String name) {
return "World," + name + ".";
}
public String getHelloWorld() {
return "Hello,World";
}
}
3.修改web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 加載Axis -->
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
4. 配置services.xml
把tomcat安裝目錄下的webapps/axis2/WEB-INF下的modules、service和conf文件件拷至HelloWorld下的WEB-INF目錄下。把lib下的如下jar包也拷過去。然後在services下新建HelloWorld/META-INF路徑,META-INF下新建services.xml,內容如下:
目錄結構
services.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<service name="HelloWorld">
<description>
HelloWorld Service Example
</description>
<parameter name="ServiceClass">
com.HelloWorld
</parameter>
<operation name="getHello">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
<operation name="getWorld">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
<operation name="getHelloWorld">
<!-- 這裏要注意,當沒有返回值時才用
org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver,沒有參數還是用RPCMessageReceiver-->
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
</service>
一定要再寫一個ServiceData.xml不然後續會報錯
<?xmlversion="1.0"encoding="UTF-8"?>
<!--此文件必須存在,否則執行異常 -->
<ServiceData>
</ServiceData>
對於service標籤的一些解釋
- < service name=“HelloWorld”> 這裏指定服務名稱。
- < description>服務描述
- < parameter name=“ServiceClass”> 服務級參數
在services.xml文件中,我們可以直接在service節點下定義參數,這些參數供消息上下文(在運行時)、AxisService或者AxisOperation訪問。參數有一個必選參數和可選參數:參數名稱是必選參數。這裏的服務參數爲指定服務類。
- < operation name=“sayHello”> 服務級消息接收器
Axis2中消息接收器是特殊的處理器,是In路徑(請求路徑)中的最後一個處理器。Web服務中的每個操作都有他自己的消息接收器,而且不同的操作可以有不同的消息接收器。消息接收器是依賴於消息交換模式的,所以我們必須爲不同的消息交換模式指定不同的消息接收器。
怎樣才能給所有的操作指定相同的消息接收器呢?只要添加服務級消息接收器即可。如此我們就不必在操作級別指定消息接收器了。我們要做的是指定服務級消息接收器。而在部署時,Axis2會自動給操作選擇正確的消息接收器。這裏我們指定
Operation 級消息接收器
前文描述瞭如何指定服務級消息接收器。但是,我們也可以爲不同的操作指定不同的消息接收器,這需要在operation中指定messageReceiver標籤
最後說明一個編寫用於部署服務組的services.xml文件的問題
要在單個服務包文件中部署多個服務,服務組是一個便捷方法。當然,這些服務之間應該存在邏輯關係。用於服務組的services.xml文件和用於單個服務的,它們之間唯一的區別就是根元素。用於服務組的,根元素是serviceGroup,我們可以在serviceGroup元素內部定義多個service元素。
<serviceGroup>
<service name=service1>
......
<service>
<service name=service2>
..........
</service>
</serviceGroup>
5.啓動Tomcat
訪問http://localhost:8080/WebserviceWeather_war_exploded/services/HelloWorld?wsdl
客戶端
package com.client;
import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class ClientTest {
public static void main(String[] args) {
String url = "http://localhost:8080/WebserviceWeather_war_exploded/services/HelloWorld";
String result = null;
try {
// 使用RPC方式調用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
// 指定調用WebService的URL
EndpointReference targetEPR = new EndpointReference(url);
options.setTo(targetEPR);
// 在創建QName對象時,QName類的構造方法的第一個參數表示WSDL文件的命名空間名,也就是<wsdl:definitions>元素的targetNamespace屬性值
// // 指定要調用的getWorld方法及WSDL文件的命名空間.....
QName opAddEntry = new QName("http://com", "getWorld");
//
// 指定getGreeting方法的參數值,如果有多個,繼續往後面增加即可,不用指定參數的名稱
Object[] opAddEntryArgs = new Object[] { "java" };
// 返回參數類型,這個和axis1有點區別
// invokeBlocking方法有三個參數,其中第一個參數的類型是QName對象,表示要調用的方法名;
// 第二個參數表示要調用的WebService方法的參數值,參數類型爲Object[];
// 第三個參數表示WebService方法的返回值類型的Class對象,參數類型爲Class[]。
// 當方法沒有參數時,invokeBlocking方法的第二個參數值不能是null,而要使用new Object[]{}
// 如果被調用的WebService方法沒有返回值,應使用RPCServiceClient類的invokeRobust方法,
// 該方法只有兩個參數,它們的含義與invokeBlocking方法的前兩個參數的含義相同
// 指定getGreeting方法返回值的數據類型的Class對象.....
Class[] classes = new Class[] { String.class };
// 調用getGreeting方法並輸出該方法的返回值.......
result = (String) serviceClient.invokeBlocking(opAddEntry,
opAddEntryArgs, classes)[0];
System.out.println(result);
// 下面是調用getHello方法的代碼,這些代碼與調用getWorld方法的代碼類似
// classes = new Class[] {String.class};
opAddEntry = new QName("http://com", "getHello");
opAddEntryArgs = new Object[] { "曹勝歡" };
System.out.println(serviceClient.invokeBlocking(opAddEntry,
opAddEntryArgs, classes)[0]);
// 下面是調用getHelloWorld方法的代碼
opAddEntry = new QName("http://com", "getHelloWorld");
System.out.println(serviceClient.invokeBlocking(opAddEntry,
new Object[]{}, classes)[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}