最近,着手學習在Java環境中開發webservice,這裏採用axis2開發。
一、 實現0配置的WebService的步驟
1.編寫一個WebService類
2.編譯這個WebService類
3.將編譯生成的.class文件直接複製到<Tomcat安裝目錄>\webapps\axis2\WEB-INF\pojo目錄中。如果pojo目錄不存在,則新建這個目錄。爲什麼是pojo目錄,稍後自會揭曉。
下面是一個簡單的WebService類
public class Axis2WebService {
public String hello(String name) {
return "Hello, " + name + "!";
}
public int getNumber() {
return new java.util.Random().nextInt();
}
public double add(double number1, double number2) {
return number1 + number2;
}
}
進行編譯得到.class文件後執行第3步,啓動tomcat(startup.bat),在瀏覽器中輸入: http://localhost:8080/axis2/services/listServices
會發現下面多了一個Axis2WebService服務,如下圖:
二 、調用WebService
1 直接在瀏覽器中調用
三個方法調用示例
http://localhost:8080/axis2/services/Axis2WebService/getNumber
http://localhost:8080/axis2/services/Axis2WebService/hello?args0=(inputparameter)
http://localhost:8080/axis2/services/Axis2WebService/add?args0=0&args1=9
其中有輸入參數時,參數名要和wsdl中描述一致,調用結果如下
2 使用Java調用WebService
2.1 使用RPC調用WebService
調用步驟:
1. 創建RPCServiceClient對象
2. 創建EndPointReference對象,並指定要訪問WebService的URL(不包含wsdl)
3. 創建描述WebService方法的參數值object[]對象
4. 創建描述WebService方法返回值類型的class[]對象
5. 創建QName對象,並指定要調用的WebService方法
6. 使用RPCServiceClient類的invokeBlocking方法調用WebService方法(invokeBlocking方法採用的是同步的方式)
這裏寫一個客戶端實例來驗證一下(需要先導入阿axis2\WEB-INF\lib文件下的jar包)
package cn.axis2.client;
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;
import org.junit.Test;
public class RPCClient {
@Test
public void test() {
try {
//創建RPCServiceClient對象
RPCServiceClient rpcClient = new RPCServiceClient();
Options options = rpcClient.getOptions();
//創建EndPointReference對象,並指定要訪問WebService的URL(
EndpointReference endpoint = new EndpointReference(
"http://localhost:8080/axis2/services/Axis2WebService");
options.setTo(endpoint);
//創建描述WebService方法的參數值object[]對象
Object[] request = new Object[] { "2", "4" };
//創建描述WebService方法返回值類型的class[]對象
Class[] responseType = new Class[] { double.class };
//創建QName對象,並指定要調用的WebService方法
QName qname = new QName("http://ws.apache.org/axis2", "add");
//使用RPCServiceClient類的invokeBlocking方法調用WebService方法
Object[] response = rpcClient.invokeBlocking(qname, request,
responseType);
System.out.println(response[0]);
response = rpcClient.invokeBlocking(new QName(
"http://ws.apache.org/axis2", "getNumber"),
new Object[] {}, new Class[] { int.class });//當沒有輸入參數時,不能用null替代new Object[]{}
System.out.println(response[0]);
response = rpcClient.invokeBlocking(new QName(
"http://ws.apache.org/axis2", "hello"),
new Object[] { "boy" }, new Class[] { String.class });
System.out.println(response[0]);
} catch (AxisFault e) {
e.printStackTrace();
}
}
}
2.2wsdl2java簡化客戶端的編寫
RPC方式調用WebService步驟多,複雜,不過axis2提供了一個更簡單的方法來訪問WebService。axis2提供一個wsdl2java命令,這個命令可以根據wsdl的內容自動生成調用WebService的客戶端Stub類。
在cmd命令行下進入axis2\bin目錄鍵入命令:
wsdl2java -uri http://localhost:8080/axis2/services/Axis2WebService?wsdl -p cn.axis.client -s -0 stub
最後在axis2\bin目錄下生成stub文件夾。
這個Axis2WebServiceStub.java就是客戶端類。通過調用類中方法就可以訪問WebService了。
創建一個java工程,將stub文件夾下的內容拷貝至工程下
package cn.axis.client;
import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.junit.Test;
public class StubClient {
@Test
public void test() {
try {
// add
Axis2WebServiceStub client = new Axis2WebServiceStub();
Axis2WebServiceStub.Add add = new Axis2WebServiceStub.Add();
add.setArgs0(1);
add.setArgs1(2);
System.out.println(client.add(add).get_return());
// getNumber
System.out.println(client.getNumber(
new Axis2WebServiceStub.GetNumber()).get_return());
// hello
Axis2WebServiceStub.Hello hello = new Axis2WebServiceStub.Hello();
hello.setArgs0("boy");
System.out.println(client.hello(hello).get_return());
} catch (AxisFault e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
很明顯,生成客戶端方式簡單得多。
3動態調用WebService
動態調用WebService,最爲基本,基於流的方式,靈活,不需要生成客戶端類。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import org.junit.Test;
public class MSPJK {
@Test
public void test() {
String wsdlUrl = "http://localhost:8080/axis2/services/Axis2WebService?wsdl";
String soap = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:axis=\"http://ws.apache.org/axis2\">"
+ "<soapenv:Header/>"
+ "<soapenv:Body>"
+ "<axis:add>"
+ "<args0>4</args0>"
+ "<args1>5</args1>"
+ "</axis:add>"
+ "</soapenv:Body>" + "</soapenv:Envelope>";
String soapAction = "http://ws.apache.org/axis2/add";
String response = getSoapStream(wsdlUrl, soap, soapAction);
System.out.println(response);
}
public String getSoapStream(String wsdlUrl, String soap, String soapAction) {
try {
URL url = new URL(wsdlUrl);
URLConnection conn = url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Length",
Integer.toString(soap.length()));
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction", soapAction);
OutputStream os = conn.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");
osw.write(soap);
osw.flush();
osw.close();
StringBuilder totalString = new StringBuilder();
String currentLine = "";
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(
is));
while ((currentLine = reader.readLine()) != null) {
totalString.append(currentLine);
}
return totalString.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
結果:
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:addResponse xmlns:ns="http://ws.apache.org/axis2"><return>9.0</return></ns:addResponse></soapenv:Body></soapenv:Envelope>
對這個進行解析就可以得到結果了。
三 、WebService中使用其他的類(自定義類)
在做項目時,往往需要自定義類,所以WebService能夠使用自定義類很重要。下面介紹一下怎麼去實現。
假設,現在服務器端有個Person類,客戶端需要直接訪問得到Person信息,該怎麼做。
package cn.axis2.myclass;
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
修改Axis2WebService.java,導入Person:(import cn.axis2.myclass.Person;)
並添加一個方法:
public Person getPerson() {
Person person = new Person();
person.setName("dsl");
person.setAge(21);
return person;
}
同時編譯Person.java和Axis2WebService.java,Axis2WebService.class拷貝至webapps\axis2\WEB-INF\pojo目錄下,Person.class拷貝至webapps\axis2\WEB-INF\classes\cn\axis2\myclass目錄下(路徑與包名一致)
在瀏覽器中刷新http://localhost:8080/axis2進入Services項,可以看見多了getPerson接口。
用wsdl2java命令重新生成客戶端類,
//getPerson
Axis2WebServiceStub.GetPerson getPerson = new Axis2WebServiceStub.GetPerson();
System.out.println(client.getPerson(getPerson).get_return().getName());
System.out.println(client.getPerson(getPerson).get_return().getAge());
這樣就可以輸出Person信息了。自定義類的使用也就實現了。
四、在沒有Servlet容器情況下使用axis2
對來axis2,它自身在二進制發行包中提供了一個簡單的HTTP服務器,這個服務器默認端口是8080,與tomcat默認端口衝突,所以要用這個HTTP服務器,得先關閉tomcat。
CMD:在axis2\bin目錄下輸: axis2server.bat
在瀏覽器中刷新http://localhost:8080/axis2/services/
可以看到axis2提供的默認服務Version
五 axis2.xml配置文件
最後講一下axis2.xml配置文件,這是axis2的核心文件,在<Tomcat安裝目錄>\webapps\axis2\WEB-INF\config目錄下。
其中幾個常用的配置有:
<!--是否熱發佈,即發佈服務時,不需要重新啓動tomcat-->
<parameter name="hotdeployment">true</parameter>
<!--是否熱更新 -->
<parameter name="hotupdate">false</parameter>
<!--配置發佈WebService服務目錄,使用POJODeployer類發佈的WebService類不能有包,這就是爲什麼前面發佈WebService時要放在pojo目錄下-->
<deployer extension=".class" directory="pojo" class="org.apache.axis2.deployment.POJODeployer"/>
<!--配置HTTP服務器 -->
<transportReceiver name="http"
class="org.apache.axis2.transport.http.SimpleHTTPServer">
<parameter name="port">8080</parameter>
</transportReceiver>