axis2強大的webservice

以前一直用axis這個web service但是從來沒有想過他調用.net的web serivce時會出現編碼問題,爲此相當的煩惱,所以改用axis2,他的畢竟會比axis1加大。

但是用到axis2時,同時又遇到了一個問題,axis2調用數據有三種方式,一般都會看到第一種RPCServiceClient此方案,但是這個方案中,居然參數無法傳入,在網上查了N多記錄,全部一樣的,別人不知道哪裏複製過來,信誓噹噹,沒有經過自己的驗證就拿出來,忽悠人,說實話,這麼多年以來,我每次查資料時,都是這樣的問題,別人總是原錯誤的代碼或是有誤的代碼來迷了我的眼睛,現在把這段不可能成功的代碼也貼出來,供大家參考,如果哪位在英文文檔中找到了設置方案,希望能給我留言或是聯繫我的QQ:106720605

以下是RPC方式,不過沒有參數的調用能成功,有參數傳入,無法傳入,我也沒有時間一點點的去看英文api,

public class Axis2Client {
    public static String target = "http://webservice.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx?wsdl";
    /**
     * @param args
     */
    public static void main(String[] args){
        try{
             // 獲得客戶端  
            RPCServiceClient serviceClient = new RPCServiceClient();
            // 可以在該對象中設置服務端的驗證信息  
            Options options = serviceClient.getOptions();  
            EndpointReference targetEPR = new EndpointReference(target);  
            options.setTo(targetEPR);
            options.setAction("http://WebXml.com.cn/getTVstationDataSet");
            // 在創建QName對象時,QName類的構造方法的第一個參數表示WSDL文件的命名空間名,也就是<wsdl:definitions>元素的targetNamespace屬性值  
            QName opAddEntry = new QName("http://WebXml.com.cn/","getTVstationDataSet");  
            // 參數,如果有多個,繼續往後面增加即可,不用指定參數的名稱  
        //    QName arg = new QName("http://WebXml.com.cn/","getTVstationDataSet",Q);
            Object[] opAddEntryArgs = new Object[] {3};  
            // 返回參數類型,這個和axis1有點區別  
            // invokeBlocking方法有三個參數,其中第一個參數的類型是QName對象,表示要調用的方法名;  
            // 第二個參數表示要調用的WebService方法的參數值,參數類型爲Object[];  
            // 第三個參數表示WebService方法的返回值類型的Class對象,參數類型爲Class[]。  
            // 當方法沒有參數時,invokeBlocking方法的第二個參數值不能是null,而要使用new Object[]{}  
            // 如果被調用的WebService方法沒有返回值,應使用RPCServiceClient類的invokeRobust方法,  
            // 該方法只有兩個參數,它們的含義與invokeBlocking方法的前兩個參數的含義相同  
            Class[] classes = new Class[] {Integer.class};
            OMElement obj=(OMElement)(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);
            System.out.println("============"+obj.toStringWithConsume());
        } catch (Exception e) {  
            e.printStackTrace();  
        } 
    }

}

據我的經驗應該就是哪裏少了一個設置,可是目前沒有辦法找到。國內也沒有哪位把研究成果公佈過。

而後就產生了第二種調用方案用serverClient但是這個方案有個最大的缺點,所有的返回的都是xml都要進行解析,實話omelement相當的不好用,不過我還是封裝了一個方案,以後哪位可以複製過去學習一下

/**
     * 用axis2通過document方式進行調用,返回xml文件,所有數據要進行xml解析
     * @author storm
     * @param target 目標地址
     * @param tarAction targetAction此處在文件可找到
     * @param namespace
     * @param method 調用的方法名
     * @param args 參數其中如無參數用null進行調用,如有參數用treeMap 其中name就是參數名,value是參數的值
     * @return 返回OMElment此爲xml對象的接口
     * @throws Exception
     */
    public OMElement getServiceReturnXML(String target,String tarAction,String namespace,String method,TreeMap<String, String> args)throws Exception{
        EndpointReference targetEPR = new EndpointReference(target);  
        ServiceClient sender = new ServiceClient();
        
        Options options = new Options();
        options.setTo(targetEPR);
        options.setSoapVersionURI(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
        options.setTransportInProtocol(Constants.TRANSPORT_HTTP);  
        
        
        if(tarAction!=null&&!tarAction.equals("")){
            options.setAction(tarAction);
        }
        sender.setOptions(options);  
        OMFactory fac = OMAbstractFactory.getOMFactory();  
        OMNamespace omNs = fac.createOMNamespace(namespace, "");  
        OMElement data = fac.createOMElement(method, omNs);  

        if(args!=null){
            for(Iterator iterator = args.keySet().iterator();iterator.hasNext();){
                String name = iterator.next().toString();
                String value = args.get(name).toString();
                OMElement inner = fac.createOMElement(name, omNs);  
                inner.setText(value);
                data.addChild(inner);
            }
        }
        OMElement result = sender.sendReceive(data);
        return result;
    }

到最後就是最合理的,也是最方案方案,用存根式來完成調用,以前兩個項目都是java的時候我會採用cxf 這樣根本沒有調用webservice的感覺,好像只是使用本地的class

這個存根也有這樣的感覺了,存根就要先用工具把這個接口生成java的根

先配置AXIS2_HOME這個路徑,注此路徑不要配置到bin這個文件夾上,不然會不成功的,

然後就直接使用wsdl2java -uri http://xxxxxxxxxxx?wsdl 註明:後面要加上wsdl

這樣就會生成一個src文件夾,裏面有你要的接口與class

 try {
               ChinaTVprogramWebServiceStub stub = new ChinaTVprogramWebServiceStub();
               GetTVchannelDataSet getTV = new GetTVchannelDataSet();
               getTV.setTheTVstationID(3);
               System.out.println(stub.getTVchannelDataSet(getTV).getGetTVchannelDataSetResult().getExtraElement().toStringWithConsume());
            } catch (AxisFault e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (XMLStreamException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

然後寫上的代碼先new出存根,每二行把你要調用的方法也new 出來,第三行,把參數置入,第四行調回數據,就這麼簡單而且數據的回來是會和你要求的數據一致。

這樣完成了axis2的使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章