歡迎光臨
每天分享高質量文章

通向架構師的道路 ( 第十二天 ) 之 Axis2 Web Service ( 三 )( 上 )

(點選上方公眾號,可快速關註)


來源:袁鳴凱 ,

blog.csdn.net/lifetragedy/article/details/7801983

一、SOAPIn Axis2

在前兩天的教程中,我們學習到了用Axis2如何進行複雜資料、簡單資料進行傳輸。

正如我在前一天教程中所說,在web service的世界裡,一切都是基於SOAP的,因此在今天我們將學習Axis2中的SOAP特性。

今天的課程將用3個例子來完成即:

  1. 客戶端與服務端使用SOAP進行通訊

  2. 服務端將Exception以SOAPFault的形式拋給客戶端

  3. 使用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” />

 

                   urn:request

 

         

 

該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

 

         

 

         org.sky.axis2.soap.SoapFaultService

 

         

 

         

 

                   

 

                            class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver” />

 

                   urn:getPrice

 

         

 

上述這個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技能

贊(0)

分享創造快樂