java:浅谈axis调用webservice接口

来源:互联网 发布:云上贵州大数据宋俊 编辑:程序博客网 时间:2024/05/16 10:18


【申明:此代码已经经过测试可以正确使用;但内容解释为个人见解,如有不准确之处,请指教。

             阅读前请先仔细阅读“【】”中的说明文字,以免与您的需求不符而浪费时间。】

【前提:对方给了一个wsdl文件,用axis根据此wsdl文件,写一个访问其webservice接口的方法。其中还知道

             了对方报文实体(RequestBody)和回复实体(ResponseBody:也就是wsdl的返回对象实体)

  流程:我方通过webservice接口(http://14.2.33.94:9103/BSBOPM/services/OPMgetMDSData)向对方发

             送报文 --->  对方收到后,再给我方一个回复。】

【开发环境:MyEclipse6.5; web项目】

【语言: java、axis1】

【接口属性:参数类型:对象(RequestBody);返回类型:对象(ResponseBody)】

步骤:

1.首先引用相关jar包:

axis-ant.jar、axis.jar、commons-discovery-0.2.jar、wsdl4j-1.5.1.jar、httpclient-4.2.1.jar、httpcore-4.2.2.jar。(httpclient-4.2.1.jar、httpcore-4.2.2.jar 这个不确定是否用过,之所以引用了这两个包,是在另一个功能中使用HttpPost进行webservice回复功能。建议:可先不需要引这两个包)。

 

2.查看wsdl文件:

注:此是已经发布成功的wsdl文件,而非其源码(.wsdd)文件。

<?xml verson="1.0">

<wsdl:definitions targetNamespace="http://service.axis.com/da/"  

                              xmlns:apachesoap="http://xml.apache.org/xml-soap"

                              xmlns:impl="http://service.axis.com/da/"

                              xmlns:intf="http://ervice.axis.com/da/"

                              xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

                            .....>

<wsdl:types>

   <schema targetNamespace="http://service.axis.com/da/"  

                    xmlns="http://www.w3.org/2001/XMLSchema">

       <import namespace="http://schemas.xmlsoap.org/soap/encoding/"  />

       <complexType name="MessageBody">

          <sequence>

              <element name="jobStatus" nillable="true" type="xsd:string" />

              <element name="jobTicket" nillable="true" type="xsd:string" />

              <element name="sendTime" nillable="true" type="xsd:string" />

              <element name="systemDate" nillable="true" type="xsd:string" />

           </sequence>

      </complexType>

 </schema>

</wsdl:types>

<wsdl:message name="MessageHandlerRequest">

  <wsdl:part name="requestBody" type="impl:MessageBody">

</wsdl:message>  

<wsdl:message name="MessageHandlerRespnse">

  <wsdl:part name="MessageHandlerReturn" type="impl:MessageBody">

</wsdl:message> 

 

<wsdl:portType name="RemoteRevServiceImpl">

   <wsdl:operation name="MessageHandler" parameterOrder="requestBody">

         <wsdl:input message="impl:MessageHandlerRequest"  name="MessageHandlerRequest" />

         <wsdl:output message="impl:MessageHandlerRequestResponse

                                name="MessageHandlerResponse" />

   </wsdl:operation>

</wsdl:portType>

【析:portType:wsdl最重要的元素,定义一了个端口;

          operation name="" :操作方法,即:可理解为:从哪个方法开始执行。

          input:一个名为“MessageHandlerReques”的输入消息;

          output:一个名为:"MessagehandlerResponse"的输出消息

 】

 

<wsdl:binding  name="OPMgetMDSDataSoapBinding"  type="impl:RemoteRevServiceImpl">

    <wsdlsoap:binding   style="rpc"  transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="MessageHandler">

        <wsdlsoap:operation soapActon="" />

           <wsdl:input name="MessageHandlerRequest">

                 <wsdlsoap:body namespace="http://service.axis.com/da/"  use="literal" />

            </wsdl:input>

             <wsdl:output  name="MessageHandlerResponse">

                  <wsdlsoap:body  namespace="http://service.axis.com/da/" use="literal" />

              </wsdl:output>

      </wsdl:operation>

  <wsdl:binding>

【析:binding中:

          name :  定义 binding 的名称;

          type: 定义绑定的端口,对应:portType name="RemoteRevServiceImpl 。

          wsdlsoap:binding中:

          style:可取值 "rpc" 或 "document"。

          transport :定义了要使用的 SOAP 协议。在这个例子中我们使用 HTTP。

          operation: 定义了每个端口提供的操作符。 并对输入和输出进行编码。在这个例子中使用了 "literal"。

  】

 

<wsdl:service name="RemoteRegvServiceImplService">

    <wsdl:port binding="impl:OPMgetMDSDataSoapBinding" name="OPMgetMDSData">

          <wsdlsoap: address location="http://14.2.33.94:9103/BSBOPM/services/OPMgetMDSData" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions> 

 

3.查看wsdl的源文件:server-config.wsdd文件。如下:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
 xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <globalConfiguration>
        <parameter name="sendMultiRefs" value="true"/>
        <parameter name="disablePrettyXML" value="true"/>
        <parameter name="dotNetSoapEncFix" value="true"/>
        <parameter name="enableNamespacePrefixOptimization" value="false"/>
        <parameter name="sendXMLDeclaration" value="true"/>
        <parameter name="sendXsiTypes" value="true"/>
        <parameter name="attachments.implementation"

                            value="org.apache.axis.attachments.AttachmentsImpl"/>
  </globalConfiguration> 
 
 <handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper" />


 <service name="RemoteRevWs" provider="java:RPC" style="rpc" use="literal">
      <parameter name="className" value="com.rx.system.ws.service.impl.RemoteRevServiceImpl" />
      <parameter name="allowedMethods" value="*" />
      <beanMapping   languageSpecificType="java:com.rx.system.ws.message.RequestBody" 

                                  qname="ns1:MessageBody"

                                  xmlns:ns1="http://service.axis.com/da/"/>
      <beanMapping   languageSpecificType="java:com.rx.system.ws.message.ResponseBody"

                                   qname="ns2:MessageBody"

                                   xmlns:ns2="http://service.axis.com/da/"/>

      【析:beanMapping:

                languageSpecificType:javaBean的实体类路径。

                qname:即限定名,是注明了命名空间的节点名字,格式:命名空间:本地名。(没有标注命名空间的 

                             节点,属于非限定名。它有可能是属于缺省命名空间,如果缺省命名空间没有定义,则属于

                             无命名空间)在xml中元素和属性都是用qname表示的。

        】


      <typeMapping   languageSpecificType="java:com.rx.system.ws.message.RequestBody"

                                 name="ns1:MessageBody"

                                 xmlns:ns1="http://service.axis.com/da/"
                                 deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"

                                 serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"/>

       <typeMapping  languageSpecificType="java:com.rx.system.ws.message.ResponseBody"

                                 qname="ns2:MessageBody"

                                 xmlns:ns2="http://service.axis.com/da/"

                                 deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"

                                 serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"/>

【析:typeMapping:

          languageSepcificType,qname与beanMapping中的一要

          serializer="org.apache.axis.encoding.ser.BeanSerializerFactory:序列化的工厂类,

          deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory反序列化的工厂类。

        (在调用方法中的registerTypeMapping会类似)

 

      <namespace>http://service.axis.com/da/</namespace>
   </service>
 <transport name="http">
  <requestFlow>
   <handler type="URLMapper" />
  </requestFlow>
 </transport>
</deployment>

 

4.实体类

public class RequestBody implements Serializable{

      private static final long servialVersionUID=1L;

      private String jobTicket;

      private String systemDate;

      private String sendTime;

      private String jobStatus;

      ......//此处省略set/get方法

  }

 

public class ResponseBody implemens Serializable{

    private static final long serialVersionUID=1L;

    private String code;

    private Sring rtnMsg;

    public ResponseBody(){}

    public ResponseBody(String code,String rtnMsg){

        this.code=code;

        this.rtnMsg=rtnMsg;

     }

     ......//此处省略set/get方法

}

【注:实体类都实现了序列化接口(serializable),这样在网络中传递对象的时候就不会出现重复的JavaBean。】

 

5.调用接口方法类

import javax.xml.namespace.QName;

import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

import org.apache.axis.encoding.ser.BeanDeserializerFactory;

import org.apache.axis.encoding.ser.BeanSerializerFactory;

 

public class TestSchedul{

     public static void main(String[] args){

            String eodPath="http://14.2.33.94:9103/BSBOPM/services/OPMgetMDSData";                 

           //此eodPath:调用的webservice接口路径,可对应到发布的wsdl中的:address location。

        

          Service  service = new Service();

            try{

                 //为要传入到接口的对象参数进行赋值,可对应到发布的wsdl中的:complexType MessageBody

                 RequestBody rb = new RequestBody();

                 rb.setJobStatu("Y");

                 rb.setJobTicket("12345678900987654321123456789000987654321");

                 rb.setSendTime("2014-10-21");

                 rb.setSystemDate("2014-10-21");

 

                 Call    call  = service.createCall();

                 call.setTimeOut(5000);

                 call.setTargetEndpointAddress(eodPath); //设置接口路径。

                

                  QName qn = new QName("http://service.axis.com/da/","MessageBody");

                  call.registerTypeMapping(

                                                              RequestBody.class,

                                                              qn,

                                                              new BeanSerializerFactory(RequestBody.class,qn),

                                                              new BeanDeserializerFacotry(RequestBody.class,qn) 

                                                          ); //这好似注册typeMapping

 

                   call.setOperationName("MessageHandler");

                   //设置操作名称,对应wsdl中的:wsdl:operation name="MessageHandler"

 

                   call.addParameter("MessageHandlerRequest",qn,ParameterMode.IN);

                  //添加参数:其格式为:参数名称,Qname,参数模式。

                     参数名称对应wsdl的<wsdl:input  name="MessageHandlerRequest" />

 

                   /*若不需要读取返回对象的属性,则可以用如下代码:

                     call.setReturnClass(org.w3c.dom.Element.class);     

                     Object pb = (Object)call.invoke(new Object[]{rb});

                      System.out.println("return type == " + pb.getClass().getName());              

                  */

 

                   //获取返回类型的值:通过<wsdl:output name="MessageHandlerResponse" />找到

                    <wsdl:message name="MessageHandlerRespnse">

                          <wsdl:part name="MessageHandlerReturn" type="impl:MessageBody">

                    </wsdl:message> 

                   QName returnQn = new QName("http://service.axis.com/da/","MessageHandlerReturn");

                 

                   call.registerTypeMapping(

                                                                ResponseBody.class,

                                                                 returnQn,

                                                                new BeanSerializerFactory(ResponseBody.class,returnQn),

                                                                new BeqanDeserializerFactory(ResponseBody.class,returnQn)

                                                         );

                   call.setReturnType(returnQn,ResponseBody.class);//对应registerTypeMapping

                 

                   ResponseBody pb =(ResponseBody)call.invoke(new Object[]{rb});//调用接口

                    System.out.println("see the return value = " + pb.getRtnMsg());

      

            }catch(Exception e){

               e.printStackTrace();

            }

     }

}

 //资料链接:

http://www.w3cschool.cn/wsdl_binding.html :简单的wsdl介绍

0 0
原创粉丝点击