(點選上方公眾號,可快速關註)
來源:袁鳴凱 ,
blog.csdn.net/lifetragedy/article/details/7801983
一、SOAPIn Axis2
在前兩天的教程中,我們學習到了用Axis2如何進行複雜資料、簡單資料進行傳輸。
正如我在前一天教程中所說,在web service的世界裡,一切都是基於SOAP的,因此在今天我們將學習Axis2中的SOAP特性。
今天的課程將用3個例子來完成即:
-
客戶端與服務端使用SOAP進行通訊
-
服務端將Exception以SOAPFault的形式拋給客戶端
-
使用SWA(Soap With Attachment)來進行附件傳送
二、客戶端與服務端使用SOAP進行通訊
來看下麵這個Web Service:
下麵是Service端的原始碼
org.sky.axis2.soap.SoapService
package org.sky.axis2.soap;
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 java.util.*;
public class SoapService {
public static OMElement requestSoap = null;
public OMElement request(OMElement soapBody) {
requestSoap = soapBody;
Iterator it = requestSoap.getChildElements();
OMElement issuerElement = (OMElement) it.next();
OMElement serialElement = (OMElement) it.next();
OMElement revocationDateElement = (OMElement) it.next();
String issuer = issuerElement.getText();
String serial = serialElement.getText();
String revocationDate = revocationDateElement.getText();
System.out.println(“issuer=====” + issuer);
System.out.println(“serial=====” + serial);
System.out.println(“revocationDate=====” + revocationDate);
OMFactory soapFactory = OMAbstractFactory.getOMFactory();
OMNamespace omNs = soapFactory.createOMNamespace(
“http://soap.axis2.sky.org”, “”);
OMElement soapResponse = soapFactory.createOMElement(“SoapResponse”,
omNs);
OMElement soapIssuer = soapFactory.createOMElement(“Issuer”, omNs);
soapIssuer.setText(“issuer: ” + issuer);
soapResponse.addChild(soapIssuer);
OMElement soapSerial = soapFactory.createOMElement(“Serial”, omNs);
soapSerial.setText(“serial: ” + serial);
soapResponse.addChild(soapSerial);
OMElement soapRevokeDate = soapFactory.createOMElement(“RevokeDate”,
omNs);
soapRevokeDate.setText(“RevocationDate: ” + revocationDate);
soapResponse.addChild(soapRevokeDate);
soapResponse.build();
return soapResponse;
}
}
來看它的service.xml的描述
This is the service for revoking certificate.
org.sky.axis2.soap.SoapService
class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver” />
該Web Service接受一個Soap請求,該請求為如下格式:
?
其中
1234567890
11111111
2007-01-01
我們假設它是一個購買圖書的定單,服務端收到這個請求後會傳回一個定單資訊給呼叫它的客戶端,服務端將傳回如下內容(此處不做任何業務處理,只是很簡單的傳值回客戶端)。
issuer: Wrox
serial: 1111111111ISBN
RevocationDate: 2012-07-29
為生成上述這個SoapResponse我們在Service端的核心程式碼如上面加粗部分的程式碼所示,由其註意這個“soapResponse.build();”。
下麵我們來看這個客戶端是怎麼寫的,我們這邊用的是非阻塞式客戶端
org.sky.axis2.soap.SoapServiceClient
package org.sky.axis2.soap;
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.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.AxisCallback;
import org.apache.axis2.context.MessageContext;
import javax.xml.namespace.QName;
public class SoapServiceClient {
private static EndpointReference targetEPR = new EndpointReference(
“http://localhost:8080/Axis2Service/services/SoapService”);
public static boolean finish = false;
public static void orderRequest() {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace omNs = factory.createOMNamespace(
“http://soap.axis2.sky.org”, “”);
OMElement issuer = factory.createOMElement(“Issuer”, omNs);
OMElement serial = factory.createOMElement(“Serial”, omNs);
OMElement revocationDate = factory.createOMElement(“RevocationDate”,
omNs);
issuer.setText(“Wrox”);
serial.setText(“1111111111ISBN”);
revocationDate.setText(“2012-07-29”);
OMElement requestSoapMessage = factory.createOMElement(“request”, omNs);
requestSoapMessage.addChild(issuer);
requestSoapMessage.addChild(serial);
requestSoapMessage.addChild(revocationDate);
requestSoapMessage.build();
Options options = new Options();
options.setTo(targetEPR);
ServiceClient sender = null;
try {
AxisCallback callback = new AxisCallback() {
public void onMessage(MessageContext msgContext) {
OMElement result = msgContext.getEnvelope().getBody()
.getFirstElement();
// System.out.println(msgContext.toString());
// System.out.println(msgContext.getEnvelope().toString());
System.out.println(msgContext.getEnvelope().getBody()
.getFirstElement());
finish = true;
}
public void onFault(MessageContext msgContext) {
System.out.println(msgContext.getEnvelope().getBody()
.getFault().toString());
}
public void onError(Exception e) {
}
public void onComplete() {
System.out.println(“Completed!!!”);
}
};
sender = new ServiceClient();
sender.setOptions(options);
System.out.println(“——-Invoke the service———“);
sender.sendReceiveNonBlocking(requestSoapMessage, callback);
synchronized (callback) {
if (!finish) {
try {
callback.wait(1000);
} catch (Exception e) {
}
}
if (!finish) {
throw new AxisFault(
“Server was shutdown as the async response take too long to complete”);
}
}
} catch (AxisFault e) {
e.printStackTrace();
} finally {
if (sender != null)
try {
sender.cleanup();
} catch (Exception e) {
}
}
}
public static void main(String[] args) {
orderRequest();
}
}
上述程式碼和前兩天的客戶端程式碼沒啥區別,我已經把核心程式碼用紅色給標粗了。
執行後行得到輸出
客戶端執行後的輸出:
服務端的輸出:
三、服務端將Exception以SOAPFault的形式拋給客戶端
上面這個例子很簡單,它展示了一個客戶端向服務端傳送一個request,服務端接收到客戶端的Request(OMElement型別)後解析並根據相應的業務邏輯向客戶端再傳回一個response(OMElement型別)的完整過程。
下麵我們要來看的是,如果客戶端在呼叫伺服器時發生任何錯誤,服務端如何把這個錯誤經過包裝後再傳回給客戶端的例子。
還記得我們在非阻塞式客戶端中有如下這樣的觸發器嗎?
public void onMessage(MessageContext msgContext) {
}
public void onFault(MessageContext msgContext) {
}
public void onError(Exception e) {
}
public void onComplete() {
}
此處的onFault就是用於接受從服務端拋過來的Exception的,我們把它稱為SOAPFault。
下麵來看一個例子,先來看Service端
org.sky.axis2.soap.SoapFaultService
package org.sky.axis2.soap;
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.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultCode;
import org.apache.axiom.soap.SOAPFaultReason;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
public class SoapFaultService {
private int i = 0;
public OMElement getPrice(OMElement request) throws AxisFault {
if (request == null) {
SOAPFault fault = getSOAPFault();
return fault;
}
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace ns = factory.createOMNamespace(“”, “”);
OMElement response = factory.createOMElement(“Price”, ns);
response.setText(String.valueOf(i++));
return response;
}
private SOAPFault getSOAPFault() {
MessageContext context = MessageContext.getCurrentMessageContext();
SOAPFactory factory = null;
if (context.isSOAP11()) {
factory = OMAbstractFactory.getSOAP11Factory();
} else {
factory = OMAbstractFactory.getSOAP12Factory();
}
SOAPFault fault = factory.createSOAPFault();
SOAPFaultCode faultCode = factory.createSOAPFaultCode(fault);
faultCode.setText(“13”);
factory.createSOAPFaultValue(faultCode);
SOAPFaultReason faultReason = factory.createSOAPFaultReason(fault);
faultReason.setText(“request can not be null”);
factory.createSOAPFaultText(faultReason);
factory.createSOAPFaultDetail(fault);
return fault;
}
}
註意加粗部分的程式碼,由其是標成紅色的程式碼為核心程式碼。
來看Service描述:
Please Type your service description here
class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver” />
上述這個WebService接受一個輸入的引數,如果輸入的內容為空,則傳回一個SoapFault,即鍵值為13,內容為” request can not be null”。
我們來看客戶端的程式碼
org.sky.axis2.soap.SoapFaultClient
package org.sky.axis2.soap;
import java.util.Iterator;
import javax.xml.namespace.QName;
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.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.AxisCallback;
import org.apache.axis2.context.MessageContext;
public class SoapFaultClient {
static boolean finish = false;
public static void main(String[] args) {
EndpointReference epr = new EndpointReference(
“http://localhost:8080/Axis2Service/services/SoapFaultService”);
ServiceClient sender = null;
try {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace ns = factory.createOMNamespace(
“http://soap.axis2.sky.org”, “”);
OMElement request = factory.createOMElement(“Price”, ns);
Options options = new Options();
options.setAction(“urn:getPrice”);
options.setTo(epr);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
AxisCallback callback = new AxisCallback() {
public void onMessage(MessageContext msgContext) {
OMElement result = msgContext.getEnvelope().getBody()
.getFirstElement();
OMElement priceElement = result;
System.out.println(“price====” + priceElement.getText());
finish = true;
}
public void onFault(MessageContext msgContext) {
QName errorCode = new QName(“faultcode”);
QName reason = new QName(“faultstring”);
// System.out.println(“on
// fault:”+msgContext.getEnvelope().getBody().getFault().toString());
OMElement fault = msgContext.getEnvelope().getBody()
.getFault();
System.out.println(“ErrorCode[“
+ fault.getFirstChildWithName(errorCode).getText()
+ “] caused by: “
+ fault.getFirstChildWithName(reason).getText());
}
public void onError(Exception e) {
}
public void onComplete() {
System.out.println(“OnComplete!!!”);
}
};
sender = new ServiceClient();
sender.setOptions(options);
sender.engageModule(“addressing”);
try {
// sender.sendReceiveNonBlocking(request, callback);
sender.sendReceiveNonBlocking(null, callback);
} catch (AxisFault e) {
System.out.println(“Exception occur!”);
System.out.println(e.getMessage());
}
synchronized (callback) {
if (!finish) {
try {
callback.wait(1000);
} catch (Exception e) {
}
}
}
} catch (AxisFault e) {
e.printStackTrace();
System.out.println(e.getMessage());
} finally {
try {
sender.cleanup();
} catch (Exception e) {
}
}
}
}
註意紅色並加粗部分的程式碼,為了抓到服務端拋過來的SoapFault我們必須使用非阻塞式,因此我們在onFault處,進行接受服務端錯誤的處理。
註意:
我們呼叫Service端時沒有傳入Service端所需要的request的引數:
// sender.sendReceiveNonBlocking(request,callback);
sender.sendReceiveNonBlocking(null,callback);
這將構成Service端丟擲SoapFault。
來看執行效果:
系列
看完本文有收穫?請轉發分享給更多人
關註「ImportNew」,提升Java技能