隨筆-95  評論-31  文章-10  trackbacks-0
               最近完成一個與IBM的醫(yī)院融合項目,使用webservice特此總結。從axis2、xfire、cxf框架中選擇了axis2原因是之前一個項目也使用axis2。
          1、首先從http://axis.apache.org/axis2/java/core/download.cgi下載最新的axis2,下載Binary Distribution zip | MD5 | PGP  和  WAR Distribution zip | MD5 | PGP 。其中WAR文件必須放入web容器的webapps里(專業(yè)點就是放入servlet engine里)因為發(fā)布的webservice都構建在此基礎上,就好比web項目要運行在J2EE容器里面一樣。文章結尾將會說明不需要部署該WAR文件,在一個自己的項目里面部署axis2并發(fā)布webservice。
          2、使用axis2讓人難于理解的地方,(個人感覺)不是寫services代碼,也不是寫Client測試代碼。而是如何配置services.xml文件,以及發(fā)布成aar文件。在說明這個問題前首先要說明下axis2處理xml的機制,Axis1.x使用DOM作為其XML表示機制,但使用DOM的缺點是:需要在內存中保存完整的對象層次結構,對于小消息,這將不是問題,但對于大型消息就是問題了。為解決這個問題,Axis2引入了新的XML表示形式即AXIOM(Axis2 Object Model),任何SOAP消息在Axis2中都表示為AXIOM。它基于Pull解析器技術,即調用者對解析器具有完全控制權,可以要求觸發(fā)下一個事件,因此具有“隨需應變構建”功能,僅在被要求時才會構建對象模型。
                下面對services,xml文件以及如何發(fā)布成aar進行簡單說明(代碼均來自官方網(wǎng)站)首先創(chuàng)建一個簡單的java類(用于發(fā)布成webservice)
           1package samples.quickstart.service.pojo;
           2
           3import java.util.HashMap;
           4
           5public class StockQuoteService {
           6    private HashMap map = new HashMap();
           7
           8    public double getPrice(String symbol) {
           9        Double price = (Double) map.get(symbol);
          10        if(price != null){
          11            return price.doubleValue();
          12        }

          13        return 42.00;
          14    }

          15
          16    public void update(String symbol, double price) {
          17        map.put(symbol, new Double(price));
          18    }

          19}
          上面代碼很簡單接著給出services.xml文件
           1<service name="StockQuoteService" scope="application">
           2    <description>
           3        Stock Quote Sample Service
           4    </description>
           5    <messageReceivers>
           6        <messageReceiver 
           7            mep="http://www.w3.org/2004/08/wsdl/in-only"
           8    class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
           9        <messageReceiver
          10            mep="http://www.w3.org/2004/08/wsdl/in-out"
          11    class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
          12    </messageReceivers>
          13    <parameter name="ServiceClass">
          14        samples.quickstart.service.pojo.StockQuoteService
          15    </parameter>
          16</service>
          service元素里面的name屬性代表該webservice的訪問名字
          messageReceivers元素定義用于處理此操作的消息接收器。
          打包:
          Axis2服務是作為Axis Archive(.aar)打包的 。這是一個jar文件,打包后具有以下結構:
          1./stock/StockQuoteService.class
          2
          3./META-INF/services.xml
          使用MyEclipse,首先選中StockQuoteService和META-INF/services.xml然后Export成.aar文件后,里面的META-INF文件夾里面不存在services.xml需要將WebRoot/META-INF里面的services挪進aar根目錄的META-INF里面。
          最后將該aar文件放入web容器webapps/axis2/WEB-INF/services里面,啟動web容器,訪問
          http://localhost:8080/axis2/services/StockQuoteService?wsdl
          這樣webservice服務發(fā)布成功,但是以上發(fā)布沒有基于SOAP標準。

                下面給出的services代碼以及Client代碼都基于AXIOM的API(代碼均來自官方網(wǎng)站示例)首先還是構建一個java類(使用AXIOM用于發(fā)布成webservice)
           1package samples.quickstart.service.axiom;
           2
           3import javax.xml.stream.XMLStreamException;
           4import org.apache.axiom.om.OMAbstractFactory;
           5import org.apache.axiom.om.OMElement;
           6import org.apache.axiom.om.OMFactory;
           7import org.apache.axiom.om.OMNamespace;
           8
           9import java.util.HashMap;
          10public class StockQuoteService {
          11    private HashMap map = new HashMap();
          12
          13    public OMElement getPrice(OMElement element) throws XMLStreamException {
          14        element.build();
          15        element.detach();
          16
          17        OMElement symbolElement = element.getFirstElement();
          18        String symbol = symbolElement.getText();
          19
          20        String returnText = "42";
          21        Double price = (Double) map.get(symbol);
          22        if(price != null){
          23            returnText  = "" + price.doubleValue();
          24        }

          25        OMFactory fac = OMAbstractFactory.getOMFactory();
          26        OMNamespace omNs =
          27            fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd""tns");
          28        OMElement method = fac.createOMElement("getPriceResponse", omNs);
          29        OMElement value = fac.createOMElement("price", omNs);
          30        value.addChild(fac.createOMText(value, returnText));
          31        method.addChild(value);
          32        return method;
          33    }

          34
          35    public void update(OMElement element) throws XMLStreamException {
          36        element.build();
          37        element.detach();
          38
          39        OMElement symbolElement = element.getFirstElement();
          40        String symbol = symbolElement.getText();
          41
          42        OMElement priceElement = (OMElement)symbolElement.getNextOMSibling();
          43        String price = priceElement.getText();
          44
          45        map.put(symbol, new Double(price));
          46    }

          47}
          上面17-18行代碼表示獲取請求參數(shù)
          25-31行代碼表示創(chuàng)建響應消息
          update方法里面的代碼類似。
          下面是services.xml文件內容
           1<service name="StockQuoteService" scope="application">
           2    <description>
           3        Stock Quote Service
           4    </description>
           5    <operation name="getPrice">
           6        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
           7    </operation>
           8    <operation name="update">
           9        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
          10    </operation>
          11    <parameter name="ServiceClass">samples.quickstart.service.axiom.StockQuoteService</parameter>
          12</service>
          service元素里面name屬性代表webservice的訪問名
          operation元素里面的name屬性代表方法
          parameter元素里面的name屬性(固定值ServiceClass)代表自定義的包名.類名
          messageReceiver元素定義用于處理此操作的消息接收器。Axis針對In-Only和In-Out操作提供了兩個無數(shù)據(jù)綁定的內置MessageReceivers;
          org.apache.axis2.reveivers.RawXMLINOnlyMessageReceiver用于In-Only操作
          org.apache.axis2.reveivers.RawXMLOutOnlyMessageReceiver用于In-Out操作
          如果沒有指定messageReceiver,則Axis2將嘗試使用org.apache.axis2.reveivers.RawXMLINOutMessageReceiver作為缺省的messageReceiver。
          上述RAWXML消息接收器將傳入SOAP消息的<Body>的內容作為OMElement傳遞給服務實現(xiàn)。此操作應作為OMElement返回SOAP響應的<Body>元素包含的XML內容。這就解釋了上述方法返回值為什么是OMElement了
          打包過程同上。啟動web容器,訪問http://localhost:8080/axis2/services/StockQuoteService?wsdl即可訪問
          客戶端測試代碼:
           1package samples.quickstart.clients;
           2
           3import org.apache.axiom.om.OMAbstractFactory;
           4import org.apache.axiom.om.OMElement;
           5import org.apache.axiom.om.OMFactory;
           6import org.apache.axiom.om.OMNamespace;
           7import org.apache.axis2.Constants;
           8import org.apache.axis2.addressing.EndpointReference;
           9import org.apache.axis2.client.Options;
          10import org.apache.axis2.client.ServiceClient;
          11
          12public class AXIOMClient {
          13
          14    private static EndpointReference targetEPR = 
          15        new EndpointReference("http://localhost:8080/axis2/services/StockQuoteService");
          16
          17    public static OMElement getPricePayload(String symbol) {
          18        OMFactory fac = OMAbstractFactory.getOMFactory();
          19        OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd""tns");
          20
          21        OMElement method = fac.createOMElement("getPrice", omNs);
          22        OMElement value = fac.createOMElement("symbol", omNs);
          23        value.addChild(fac.createOMText(value, symbol));
          24        method.addChild(value);
          25        return method;
          26    }

          27
          28    public static OMElement updatePayload(String symbol, double price) {
          29        OMFactory fac = OMAbstractFactory.getOMFactory();
          30        OMNamespace omNs = fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd""tns");
          31
          32        OMElement method = fac.createOMElement("update", omNs);
          33
          34        OMElement value1 = fac.createOMElement("symbol", omNs);
          35        value1.addChild(fac.createOMText(value1, symbol));
          36        method.addChild(value1);
          37
          38        OMElement value2 = fac.createOMElement("price", omNs);
          39        value2.addChild(fac.createOMText(value2,
          40                                         Double.toString(price)));
          41        method.addChild(value2);
          42        return method;
          43    }

          44
          45    public static void main(String[] args) {
          46        try {
          47            OMElement getPricePayload = getPricePayload("WSO");
          48            OMElement updatePayload = updatePayload("WSO"123.42);
          49            Options options = new Options();
          50            options.setTo(targetEPR);
          51            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
          52
          53            ServiceClient sender = new ServiceClient();
          54            sender.setOptions(options);
          55
          56            sender.fireAndForget(updatePayload);
          57            System.err.println("price updated");
          58            OMElement result = sender.sendReceive(getPricePayload);
          59
          60            String response = result.getFirstElement().getText();
          61            System.err.println("Current price of WSO: " + response);
          62
          63        }
           catch (Exception e) {
          64            e.printStackTrace();
          65        }

          66    }

          67    
          68}

          最后如果想得到某個已經(jīng)寫好的服務類的wsdl描述文件,使用java2wsdl工具。
          首先配置Axis2_HOME路徑(名字必須是這樣,否則配置較麻煩),然后配置PATH添加%Axis2_HOME%\bin,最后打開dos窗口(如果需要對test.class文件生成wsdl描述符),那么進入該Test.class根目錄下一般就是在classes目錄,輸入java2wsdl -cp . -cn 包名.Test -of Test.wsdl執(zhí)行成功后會在classes根目錄生成wsdl文件,可以交給對方生成客戶端測試代碼,此次與IBM融合就使用這種方法。

          未完待續(xù)。。。
          posted on 2011-03-04 17:08 朔望魔刃 閱讀(2984) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 曲周县| 房山区| 侯马市| 西充县| 寿光市| 常宁市| 黔西| 叶城县| 岳普湖县| 友谊县| 莲花县| 永吉县| 平陆县| 台南市| 策勒县| 恩平市| 淅川县| 陵川县| 岐山县| 洪泽县| 泊头市| 唐河县| 讷河市| 徐水县| 都兰县| 荥阳市| 道真| 涡阳县| 昌平区| 德清县| 旬邑县| 介休市| 嵊州市| 梅州市| 六枝特区| 哈密市| 富宁县| 马公市| 奎屯市| 新竹县| 宝兴县|