本文是在理解官方指南的基礎上,用實例實現Axis2提供的4種調用機制,并給出測試結果。
author: ZJ 07-3-13
Blog: http://zhangjunhd.blog.51cto.com/
author: ZJ 07-3-13
Blog: http://zhangjunhd.blog.51cto.com/
1.使用Axis2的底層API開發Web Service Server端
1.1創建一個WebService(取名為MyService)
在MyService中有兩個operations,如下所示。
1.1創建一個WebService(取名為MyService)
在MyService中有兩個operations,如下所示。
public void ping(OMElement element){}//IN-ONLY模式。僅僅接收OMElement,并對其處理。
public OMElement echo(OMElement element){}//IN_OUT模式。接收OMElemen,并返回OMElement。
public OMElement echo(OMElement element){}//IN_OUT模式。接收OMElemen,并返回OMElement。
1.2如何寫Web Service
1)創建實現服務的類。
1)創建實現服務的類。
2)創建services.xml來解析這個Web Service。
3)將其打包成一個*.aar文檔(Axis Archive)。
4)部署Web Service。
1.2.1 創建實現服務的類
此類中提供的方法必須與Web Service(在services.xml中聲明)中的operations對應。除非你提供了數據綁定,否則所有的方法只能接收一個參數,其類型為OMElement。
此類中提供的方法必須與Web Service(在services.xml中聲明)中的operations對應。除非你提供了數據綁定,否則所有的方法只能接收一個參數,其類型為OMElement。
public class MyService{
public void ping(OMElement element){...}
public OMElement echo(OMElement element){...}
}
public void ping(OMElement element){...}
public OMElement echo(OMElement element){...}
}
MyService.java
package userguide.example1;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import javax.xml.stream.XMLStreamException;
import org.apache.axis2.AxisFault;
import javax.xml.stream.XMLStreamException;
public class MyService {
public OMElement echo(OMElement element) throws XMLStreamException {
//Praparing the OMElement so that it can be attached to another OM Tree.
//First the OMElement should be completely build in case it is not fully built and still
//some of the xml is in the stream.
element.build();
//Secondly the OMElement should be detached from the current OMTree so that it can
// be attached some other OM Tree. Once detached the OmTree will remove its
// connections to this OMElement.
element.detach();
return element;
}
public void ping(OMElement element) throws XMLStreamException {
//Do some processing
}
public void pingF(OMElement element) throws AxisFault{
throw new AxisFault("Fault being thrown");
}
}
public OMElement echo(OMElement element) throws XMLStreamException {
//Praparing the OMElement so that it can be attached to another OM Tree.
//First the OMElement should be completely build in case it is not fully built and still
//some of the xml is in the stream.
element.build();
//Secondly the OMElement should be detached from the current OMTree so that it can
// be attached some other OM Tree. Once detached the OmTree will remove its
// connections to this OMElement.
element.detach();
return element;
}
public void ping(OMElement element) throws XMLStreamException {
//Do some processing
}
public void pingF(OMElement element) throws AxisFault{
throw new AxisFault("Fault being thrown");
}
}
1.2.2 創建services.xml
Axis2使用services.xml來充當一個Web Servicea的配置文件。每一個使用Axis2部署的Web Service都必須擁有一個services.xml。
Axis2使用services.xml來充當一個Web Servicea的配置文件。每一個使用Axis2部署的Web Service都必須擁有一個services.xml。
<services>
<description>
This is a sample Web Service with two operations,echo and ping.
</description>
<parameter name=”ServiceClass” locked=”false”>
userguide.example1.MyService
</parameter>
<operation name=”echo”>
<messageReceiver class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver”/>
<actionMapping>urn:echo</actionMapping>
</operation>
<operation name=”ping”>
<messageReceiver class=”org.apache.receivers.RawXMLINOnlyMessageReceiver”/>
<actionMapping>urn:ping</actionMapping>
</operation>
</service>
<description>
This is a sample Web Service with two operations,echo and ping.
</description>
<parameter name=”ServiceClass” locked=”false”>
userguide.example1.MyService
</parameter>
<operation name=”echo”>
<messageReceiver class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver”/>
<actionMapping>urn:echo</actionMapping>
</operation>
<operation name=”ping”>
<messageReceiver class=”org.apache.receivers.RawXMLINOnlyMessageReceiver”/>
<actionMapping>urn:ping</actionMapping>
</operation>
</service>
注:The actionMapping is required only if you want to enable WS-Addressing.
可以創建一個services.xml,其中包含一組服務。這樣在運行期,你可以在這些服務間共享信息。
可以創建一個services.xml,其中包含一組服務。這樣在運行期,你可以在這些服務間共享信息。
<serviceGroup>
<service name=”Service1”>
<!--details for Services1-->
</service>
<service name=”Service2”>
<!--details for Services2-->
</service>
<module ref=”ModuleName”/>
<parameter name=”serviceGroupParam1” locked=”false”>value1</parameter>
</serviceGroup>
<service name=”Service1”>
<!--details for Services1-->
</service>
<service name=”Service2”>
<!--details for Services2-->
</service>
<module ref=”ModuleName”/>
<parameter name=”serviceGroupParam1” locked=”false”>value1</parameter>
</serviceGroup>
注:name of the service is a compulsory attribute.
1.2.3打包與部署
這里不再詳述,參見《基于Tomcat5.0和Axis2開發Web Service應用實例 》。
這里不再詳述,參見《基于Tomcat5.0和Axis2開發Web Service應用實例 》。
2.使用Axis2底層APIs實現Web Service客戶端
2.1ClientUtil
創建一個客戶端通用的SOAP包裝Util文件。封裝"getEchoOMElement"和"getPingOMElement"分別對應"echo"和"ping"這兩個operation。
2.1ClientUtil
創建一個客戶端通用的SOAP包裝Util文件。封裝"getEchoOMElement"和"getPingOMElement"分別對應"echo"和"ping"這兩個operation。
ClientUtil.java
package userguide.clients;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
public class ClientUtil {
public static OMElement getEchoOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("echo", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Echo String "));
method.addChild(value);
return method;
}
public static OMElement getPingOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("ping", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Ping String "));
method.addChild(value);
return method;
}
}
public static OMElement getEchoOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("echo", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Echo String "));
method.addChild(value);
return method;
}
public static OMElement getPingOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("ping", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Ping String "));
method.addChild(value);
return method;
}
}
2.2EchoBlockingClient
Axis2向用戶提供了從blocking single channel調用到non-blocking dual channel調用的多種調用Web Service的模式。下面用最簡單的blocking調用機制來實現”MyService”中的"echo" operation。
Axis2向用戶提供了從blocking single channel調用到non-blocking dual channel調用的多種調用Web Service的模式。下面用最簡單的blocking調用機制來實現”MyService”中的"echo" operation。
EchoBlockingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Sample for synchronous single channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoBlockingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://localhost:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR); // this sets the location of MyService service
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
OMElement result = sender.sendReceive(payload);
System.out.println(result);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
* Sample for synchronous single channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoBlockingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://localhost:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR); // this sets the location of MyService service
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
OMElement result = sender.sendReceive(payload);
System.out.println(result);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
綠色部分顯示了為了調用一個Web Service而需要對operation作的設置。剩下的部分是用來創建OMElement,用來發送和顯示相應的OMElement。
結果:
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
2.3 PingClient
在”MyService”中,我們有一種IN-ONLY模式的名為"ping"的operation。應用它的客戶端代碼如下:
PingClient.java
在”MyService”中,我們有一種IN-ONLY模式的名為"ping"的operation。應用它的客戶端代碼如下:
PingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Sample for fire-and-forget service invocation
* Message Exchage Pattern IN-Only
*/
public class PingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://localhost:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getPingOMElement();
Options options = new Options();
options.setTo(targetEPR);
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
serviceClient.fireAndForget(payload);
/**
* We have to block this thread untill we send the request , the problem
* is if we go out of the main thread , then request wont send ,so
* you have to wait some time :)
*/
Thread.sleep(500);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
* Sample for fire-and-forget service invocation
* Message Exchage Pattern IN-Only
*/
public class PingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://localhost:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getPingOMElement();
Options options = new Options();
options.setTo(targetEPR);
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
serviceClient.fireAndForget(payload);
/**
* We have to block this thread untill we send the request , the problem
* is if we go out of the main thread , then request wont send ,so
* you have to wait some time :)
*/
Thread.sleep(500);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
由于我們在訪問一個IN-ONLY模式的operation,所以我們可以直接使用ServiceClient中的"fireAndForget()"方法來調用這個operation。而且那樣做的話,不會阻塞發起端,因此,它會立刻將控制權返回給客戶端。
2.4 EchoNonBlockingClient
在客戶端EchoBlockingClient,一旦調用"serviceClient.sendReceive(payload);",客戶端將會被阻 塞直到operation完成。這種方式在有很多Web Service需要在一個單一的客戶端應用程序中啟動時很不可取。一種解決方法是使用Non-Blocking API來調用這些Web Services。Axis2提供給用戶一種基于回叫機制的non-blocking API。
EchoNonBlockingClient.java
在客戶端EchoBlockingClient,一旦調用"serviceClient.sendReceive(payload);",客戶端將會被阻 塞直到operation完成。這種方式在有很多Web Service需要在一個單一的客戶端應用程序中啟動時很不可取。一種解決方法是使用Non-Blocking API來調用這些Web Services。Axis2提供給用戶一種基于回叫機制的non-blocking API。
EchoNonBlockingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
/**
* Sample for asynchronous single channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoNonBlockingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
sender = new ServiceClient();
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) { }
}
}
}
* Sample for asynchronous single channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoNonBlockingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
sender = new ServiceClient();
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) { }
}
}
}
結果:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
sender.sendReceiveNonBlocking(payload, callback);這個調用接受一個callback對象作為參數。Axis2客戶端API提供了一個抽象類CallBack,其中提供了方法:
public abstract void onComplete(AsyncResult result);
public abstract void onError(Exception e);
public boolean isComplete() {}
public abstract void onError(Exception e);
public boolean isComplete() {}
用戶需要重寫"onComplete " 和 "onError "方法。一旦客戶端收到Web Service的response,onComplete方法將會被調用,這樣將中止阻塞狀態。
2.5EchoNonBlockingDualClient
當調用的Web Service需要很長一段時間來完成時,這種由Non-Blocking API提供的解決方式將有一定的局限性。這種局限性是由使用單一的傳輸連接來調用Web Service并接收response造成的。換句話說,客戶端提供一種沒有阻塞的調用機制,但request和response的傳輸使用單一的傳輸 (雙工方式)連接(如HTTP)。長時間運行的Web Service調用或Web Service調用使用單工傳輸方式(如SMTP)不能簡單地利用一個沒有阻塞的調用。
一種嘗試地解決方法是request和response各自使用單獨的傳輸連接(單工或雙工均可)。這種方式產生的問題是如何解決相關性(關聯 request和response)。WS-Addressing提供了一種很好的解決方法,在頭中使用<wsa:MessageID> 和 <wsa:RelatesTo> 標簽。Axis2對這種基于關聯機制的尋址方式提供了支持。
用戶可以選擇Blocking 或Non-Blocking APIs的Web Service,并使用兩個傳輸連接。通過使用一個布爾標記,同一個API可以調用多個在兩個傳輸連接上的Web Services(IN-OUT operations)。下例使用Non-Blocking API 以及兩個傳輸連接來實現上文中提到的"echo" operation。
EchoNonBlockingDualClient.java
當調用的Web Service需要很長一段時間來完成時,這種由Non-Blocking API提供的解決方式將有一定的局限性。這種局限性是由使用單一的傳輸連接來調用Web Service并接收response造成的。換句話說,客戶端提供一種沒有阻塞的調用機制,但request和response的傳輸使用單一的傳輸 (雙工方式)連接(如HTTP)。長時間運行的Web Service調用或Web Service調用使用單工傳輸方式(如SMTP)不能簡單地利用一個沒有阻塞的調用。
一種嘗試地解決方法是request和response各自使用單獨的傳輸連接(單工或雙工均可)。這種方式產生的問題是如何解決相關性(關聯 request和response)。WS-Addressing提供了一種很好的解決方法,在頭中使用<wsa:MessageID> 和 <wsa:RelatesTo> 標簽。Axis2對這種基于關聯機制的尋址方式提供了支持。
用戶可以選擇Blocking 或Non-Blocking APIs的Web Service,并使用兩個傳輸連接。通過使用一個布爾標記,同一個API可以調用多個在兩個傳輸連接上的Web Services(IN-OUT operations)。下例使用Non-Blocking API 以及兩個傳輸連接來實現上文中提到的"echo" operation。
EchoNonBlockingDualClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
import javax.xml.namespace.QName;
/**
* Sample for asynchronous dual channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
* Ulitmate asynchronous service invocation sample.
*/
public class EchoNonBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
options.setAction("urn:echo"); // this is the action mapping we put within the service.xml
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);//見注解①
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//have to ignore this
}
}
}
}
* Sample for asynchronous dual channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
* Ulitmate asynchronous service invocation sample.
*/
public class EchoNonBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
options.setAction("urn:echo"); // this is the action mapping we put within the service.xml
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);//見注解①
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//have to ignore this
}
}
}
}
注解①
RE: [Axis2] 0.95 WS-Addressing web SERVICE-SIDE: module not found
I now have managed to get EchoNonBlockingDualClient working. I still can't get the original code to work, where ever I put addressing-0.95.mar, but the ConfigurationContext works.
The code I ended up with was:
RE: [Axis2] 0.95 WS-Addressing web SERVICE-SIDE: module not found
I now have managed to get EchoNonBlockingDualClient working. I still can't get the original code to work, where ever I put addressing-0.95.mar, but the ConfigurationContext works.
The code I ended up with was:
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"C:\\axis2", null);
sender = new ServiceClient(sysContext, null);
.createConfigurationContextFromFileSystem(
"C:\\axis2", null);
sender = new ServiceClient(sysContext, null);
with no need, obviously, for the .engageModule method.
I did discover though that the directory which the ConfigurationContext points to has to have two directories within it: "conf", which must contain the axis.xml configuration file, and the "modules" directory which contains addressing-0.95.mar.
I did discover though that the directory which the ConfigurationContext points to has to have two directories within it: "conf", which must contain the axis.xml configuration file, and the "modules" directory which contains addressing-0.95.mar.
在方法"options.setUseSeparateListener(...)"中的布爾標記通知通知Axis2引擎使用兩個不同的傳輸連接來分別處
理request和response。Finally中的
"serviceClient.finalizeInvoke()"方法通知Axis2引擎停用客戶端的用于接收response的listener。
在我們運行客戶端的例程之前,我們還有一件事情要做。如前面提到的,Axis2使用基于地址的關聯機制,因此我們必須在服務器端和客戶端“搭建”尋址模塊。
在我們運行客戶端的例程之前,我們還有一件事情要做。如前面提到的,Axis2使用基于地址的關聯機制,因此我們必須在服務器端和客戶端“搭建”尋址模塊。
結果:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://59.14.131.187:6060/axis2/services/__ANONYMOUS_SERVICE__/__OPERATION_OUT_IN__
</wsa:To>
<wsa:ReplyTo>
<wsa:Address>
http://www.w3.org/2005/08/addressing/anonymous
</wsa:Address>
</wsa:ReplyTo>
<wsa:From>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:From>
<wsa:FaultTo>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:FaultTo>
<wsa:MessageID>
urn:uuid:B087CBB98F1B51A24711742241136206
</wsa:MessageID>
<wsa:Action>urn:echo</wsa:Action>
<wsa:RelatesTo wsa:RelationshipType="wsa:Reply">
urn:uuid:CA4B9513377E6E9E1511742241130391
</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://59.14.131.187:6060/axis2/services/__ANONYMOUS_SERVICE__/__OPERATION_OUT_IN__
</wsa:To>
<wsa:ReplyTo>
<wsa:Address>
http://www.w3.org/2005/08/addressing/anonymous
</wsa:Address>
</wsa:ReplyTo>
<wsa:From>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:From>
<wsa:FaultTo>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:FaultTo>
<wsa:MessageID>
urn:uuid:B087CBB98F1B51A24711742241136206
</wsa:MessageID>
<wsa:Action>urn:echo</wsa:Action>
<wsa:RelatesTo wsa:RelationshipType="wsa:Reply">
urn:uuid:CA4B9513377E6E9E1511742241130391
</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
[SimpleHTTPServer] Stop called
2.6 實現服務器端的尋址
根據Axis2的結構,尋址模塊在"pre-dispatch"階段已經給出它的句柄。因此,所謂的“搭建”僅僅是在”axis2.xml”(注意不是 services.xml)增加一個模塊的引用?,F在將下面這行字加入到axis2.xml,該文件在"/webapps/axis2/WEB- INF/conf"目錄下。
根據Axis2的結構,尋址模塊在"pre-dispatch"階段已經給出它的句柄。因此,所謂的“搭建”僅僅是在”axis2.xml”(注意不是 services.xml)增加一個模塊的引用?,F在將下面這行字加入到axis2.xml,該文件在"/webapps/axis2/WEB- INF/conf"目錄下。
<module ref="addressing"/>
注: 一旦你改變了axis2.xml,你必須重啟這個servlet容器,改變才能生效。
2.7 實現客戶端的尋址
有兩種方式。
一種方法是在%Axis2_HOME%\axis2-std-1.0-bin\modules目錄下得到addressing-< version>.mar。并且在你的classpath中對其可見。(此種方法目前,我還沒有調試成功,具體見注解①。下面的第二種方法可用)
另一種方法是創建一個ConfigurationContext,指定一個repository位置。Axis2支持repository的方式來保存服務和模塊。
你可以使用二進制distribution作為repository,只要它含有一個Axis2 repository認可的repository結構(其中應包含services和modules目錄)。ConfigurationContext 中含有Axis2體系的運行時的上下文信息。
如果你解壓一個標準的二進制distribution到目錄(譬如)$user_home/axis2/dist, 那么在 sender = new ServiceClient();之前加入(具體見EchoNonBlockingDualClient.java):
有兩種方式。
一種方法是在%Axis2_HOME%\axis2-std-1.0-bin\modules目錄下得到addressing-< version>.mar。并且在你的classpath中對其可見。(此種方法目前,我還沒有調試成功,具體見注解①。下面的第二種方法可用)
另一種方法是創建一個ConfigurationContext,指定一個repository位置。Axis2支持repository的方式來保存服務和模塊。
你可以使用二進制distribution作為repository,只要它含有一個Axis2 repository認可的repository結構(其中應包含services和modules目錄)。ConfigurationContext 中含有Axis2體系的運行時的上下文信息。
如果你解壓一個標準的二進制distribution到目錄(譬如)$user_home/axis2/dist, 那么在 sender = new ServiceClient();之前加入(具體見EchoNonBlockingDualClient.java):
new ServiceClient();之前加入(具體見EchoNonBlockingDualClient.java):
ConfigurationContext configContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
ConfigurationContext configContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
用"sender = new ServiceClient(configContext, null);" 替換 "sender = new ServiceClient();"
這樣可以在客戶端和服務器端都實現尋址。
這樣可以在客戶端和服務器端都實現尋址。
2.8 EchoBlockingDualClient
這又是一個兩路的傳輸的request/response客戶端,但這次,我們使用一個Blocking API。實現機制和EchoNonBlockingDualClient差不多,唯一的不同是,這里不需要使用一個callback對象來處理 response。
EchoBlockingDualClient.java
這又是一個兩路的傳輸的request/response客戶端,但這次,我們使用一個Blocking API。實現機制和EchoNonBlockingDualClient差不多,唯一的不同是,這里不需要使用一個callback對象來處理 response。
EchoBlockingDualClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import java.io.StringWriter;
import javax.xml.stream.XMLOutputFactory;
import java.io.StringWriter;
/**
* Sample for synchronous dual channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setAction("urn:echo");
//The boolean flag informs the axis2 engine to use two separate transport connection
//to retrieve the response.
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
//Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
StringWriter writer = new StringWriter();
result.serialize(XMLOutputFactory.newInstance().createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally{
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//
}
}
}
}
* Sample for synchronous dual channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setAction("urn:echo");
//The boolean flag informs the axis2 engine to use two separate transport connection
//to retrieve the response.
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
//Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
StringWriter writer = new StringWriter();
result.serialize(XMLOutputFactory.newInstance().createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally{
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//
}
}
}
}
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>Axis2 Echo String </example1:Text>
</example1:echo>
[SimpleHTTPServer] Stop called