axis2强大的webservice

来源:互联网 发布:linux ftp软件包下载 编辑:程序博客网 时间:2024/06/05 17:26

以前一直用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的使用。

0 0