SOAP中复杂类型(JavaBean)调用实例实践

类别:.NET开发 点击:0 评论:0 推荐:

SOAP中复杂类型(JavaBean)调用实例实践

 

使用工具:axis-1_1

                Tomcat 5.2.x

IDE: Eclipse 3.1

 

一、简单开始:

1、创建一个JavaBean类     Student.java

package com.kevinGQ.service.axis.model;

 

import java.io.Serializable;

 

public class Student implements Serializable{

       private String _name;

       private String _id;

       private String _comment;

 

       public Student(){}

      

       public Student(String name, String id, String comment){

              _name = name;

              _id = id;

              _comment = comment;

       }

      

       public String getName(){

              return _name;

       }

      

       public void setName(String name){

              _name = name;

       }

      

       public String getId(){

              return _id;

       }

      

       public void setId(String id){

              _id = id;

       }

      

       public String getComment(){

              return _comment;

       }

      

       public void setComment(String comment){

              _comment = comment;

       }

}

 

2、写Service程序

package com.kevinGQ.service.axis.service;

 

import com.kevinGQ.service.axis.model.Student;

 

public class GetStudentService {

       public Student getAStudent(String name){

              Student a = new Student("a","10001","I'm A");

              return a;

       }

}

 

3、部署axis及部署service

a. 从axis-1_1.zip中将axis-1_1/webapps/axis 文件夹拷贝到Tomcat 5.0.x/webapps/

b. 打开webapps/axis/WEB-INF/server-config.wsdd进行编辑,在<deployment>标签下插入如下片断

<service name="StudentInfoService" provider="java:RPC">

        <parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"/>

        <parameter name="allowedMethods" value="*"/>

       <beanMapping qname="myNS:Student" xmlns:myNS="urn:StudentInfoService" languageSpecificType="java:com.kevinGQ.service.axis.model.Student"/>

 </service>

片断中StudentInfoService是这个web service的名字,在客户端编码的时候需要用到。

<parameter name="className" value="com.kevinGQ.service.axis.service.GetStudentService"/>

中说明了这个服务提供的类,包括package的完整类名。

<parameter name="allowedMethods" value="*"/>中说明这个服务中可供给外部调用的方法有哪些,*表示全部函数,现在也可以把*改成getAStudent.

<beanMapping qname="myNS:Student" xmlns:myNS="urn:StudentInfoService" languageSpecificType="java:com.kevinGQ.service.axis.model.Student"/>中说明对于这个JavaBean的传输需要如何对它进行serializing和de-serializing,说明的目的在于绑定JavaBean的对象类别。注意标签中说明的名字空间。这个标签其实是如下标签的一个简写:

<typeMapping qname="myNs:Student" xmlns:ns="urn:StudentInfoService"

             languageSpecificType="java: com.kevinGQ.service.axis.model.Student "

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

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

             encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

 

c. 把编译好的Student.class 和 GetStudentService.class(在它们各自的包内) 放到axis/WEB-INF/classes/.

 

4、启动Tomcat, 访问http://localhost:8080/axis/admin.html,查看你部署的服务

 

5、编写客户端

我是在Eclipse里完成代码的编写,编译及运行需要把axis-1_1/lib/ 除了axis_ant.jar外7个jar文件导入到classpath.

package com.kevinGQ.service.axis.client;

 

import java.net.URL;

 

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.XMLType;

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

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

 

import com.kevinGQ.service.axis.model.Student;

 

public class GetAStudentClient {

       public static void main(String [] args) throws Exception

    {

              Service service = new Service();

        Call call = (Call) service.createCall();

        QName qn = new QName("urn:StudentInfoService","Student");

        call.registerTypeMapping(Student.class,qn,

                      new BeanSerializerFactory(Student.class, qn),

                            new BeanDeserializerFactory(Student.class, qn)

        );

        try{

               call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/StudentService"));

               call.setOperationName(new QName("StudentInfoService","getAStudent"));

               call.addParameter("arg1",XMLType.XSD_STRING, ParameterMode.IN);

               call.setReturnClass(Student.class);

               Student a = (Student) call.invoke(new Object[]{"a"});

               System.out.println(a.getId());

        }catch(Exception e) {

            System.out.println( "Error : " + e.toString());

        }       

    }

}

红色代码部分表明任意的一个字符串,因为getAStudent方法的参数对返回的结果没有影响,这里只是象征性的传递一个参数。加粗的部分是需要在Client端说明要serialize和de-serialize的JavaBean类别,参数的说明可参考axis api 文档。

要得到运行的结果,客户端这边需要得到Student.class文件,可是如果对于一个不在本机的服务,如何得到这个Student.class呢?——你需要阅读一下这个WebService的wsdl文档,里面有对这个JavaBean对象中各个域的说明,根据JavaBean的编码规范,你自己编写编译就得到了Student.class文件。

 

二、稍微深入

我想得到的是一个Student的数组怎么办呢?

你只有稍做修改:

1、服务端的一个新类 StudentLib.java

package com.kevinGQ.service.axis.model;

 

import java.util.ArrayList;

 

public class StudentLib {

       ArrayList studentLib = null;

      

       public StudentLib(){

              studentLib = new ArrayList();

       }

      

       public void addStudent(Student s){

              studentLib.add(s);

       }

      

       public ArrayList getStudents(String name, String id){

              ArrayList list = new ArrayList();

              for(int i = 0; i < studentLib.size(); i++){

                     if(this.get(i).getName().equals(name)

                            && this.get(i).getId().equals(id)){

                                   list.add(this.get(i));

                            }

              }

              return list;

       }

      

       public Student get(int index){

              return (Student)studentLib.get(index);

       }

}

这个类只不过是为了实现稍微复杂点的逻辑功能而写。注意getStudents方法返回的是ArrayList类型的引用。因为SOAP中支持的数据类型包含java中ArrayList,所以用这个类型会方便很多。

 

2、扩展Service程序

package com.kevinGQ.service.axis.service;

 

import java.util.ArrayList;

 

import com.kevinGQ.service.axis.model.Student;

import com.kevinGQ.service.axis.model.StudentLib;

 

public class GetStudentService {

       public ArrayList getStudent(){

              ArrayList students = new ArrayList();

              Student a = new Student("a","10001","I'm A");

              Student b = new Student("a","10002","I'm B");

              Student c = new Student("a","10001","I'm A, I'm not C");

              StudentLib lib = new StudentLib();

              lib.addStudent(a);

              lib.addStudent(b);

              lib.addStudent(c);

             

              students = lib.getStudents("a","10001");

              return students;

       }

       public Student getAStudent(String name){

              Student a = new Student("a","10001","I'm A");

              return a;

       }

}

加粗的地方为添加的新的方法,我们接着要在服务端描述它

 

3、部署service

把刚才添加到server-config.wsdd的那个片断再拿出来看看,好像不用修改(只要你在allowedMethods的地方表明允许暴露的方法的是*)

 

4、写个客户端看看

package com.kevinGQ.service.axis.client;

 

import java.net.URL;

import java.util.ArrayList;

 

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

import org.apache.axis.encoding.XMLType;

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

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

 

import com.kevinGQ.service.axis.model.Student;

 

import javax.xml.namespace.QName;

import javax.xml.rpc.ParameterMode;

 

public class GetStudentClient {

      

       public static void main(String [] args) throws Exception

    {

              Service service = new Service();

        Call call = (Call) service.createCall();

        QName qn = new QName("urn:StudentInfoService","Student");

        call.registerTypeMapping(Student.class,qn,

                      new BeanSerializerFactory(Student.class, qn),

                            new BeanDeserializerFactory(Student.class, qn));

        try{

               call.setTargetEndpointAddress(new URL("http://localhost:8080/axis/services/StudentService"));

               call.setOperationName(new QName("StudentInfoService","getStudent"));

;

               call.setReturnClass(ArrayList.class);

               ArrayList result = (ArrayList) call.invoke(new Object[]{});

               for(int i = 0; i < result.size(); i++){

                      Student stu = (Student)result.get(i);

                      System.out.println(stu.getName()+" "+stu.getId()+" "+stu.getComment());

               }

        }catch(Exception e) {

            System.out.println( "Error : " + e.toString());

        }       

    }

}

和第一个客户端很相似吧。注意把Call返回的类型设为ArrayList,看代码中加粗部分!

结果输出了2条记录,和预期的一样。要不,你试试。

 

 

附:文中描述服务的wsdl.xml
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://localhost:8080/axis/services/StudentInfoService" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/axis/services/StudentInfoService" xmlns:intf="http://localhost:8080/axis/services/StudentInfoService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="urn:StudentInfoService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <schema targetNamespace="urn:StudentInfoService" xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
      <complexType name="Student">
         <sequence>
           <element name="comment" nillable="true" type="xsd:string"/>
           <element name="name" nillable="true" type="xsd:string"/>
           <element name="id" nillable="true" type="xsd:string"/>
         </sequence>
      </complexType>
    </schema>
  </wsdl:types>
  <wsdl:message name="getAStudentRequest">
    <wsdl:part name="name" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="getAStudentResponse">
    <wsdl:part name="getAStudentReturn" type="tns1:Student"/>
  </wsdl:message>
  <wsdl:message name="getStudentResponse">
    <wsdl:part name="getStudentReturn" type="soapenc:Array"/>
  </wsdl:message>
  <wsdl:message name="getStudentRequest">
  </wsdl:message>
  <wsdl:portType name="GetStudentService">
    <wsdl:operation name="getStudent">
      <wsdl:input message="impl:getStudentRequest" name="getStudentRequest"/>
      <wsdl:output message="impl:getStudentResponse" name="getStudentResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getAStudent" parameterOrder="name">
      <wsdl:input message="impl:getAStudentRequest" name="getAStudentRequest"/>
      <wsdl:output message="impl:getAStudentResponse" name="getAStudentResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="StudentInfoServiceSoapBinding" type="impl:GetStudentService">
    <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getStudent">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getStudentRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://service.axis.service.kevinGQ.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getStudentResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/StudentInfoService" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getAStudent">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getAStudentRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://service.axis.service.kevinGQ.com" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getAStudentResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/StudentInfoService" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="GetStudentServiceService">
    <wsdl:port binding="impl:StudentInfoServiceSoapBinding" name="StudentInfoService">
      <wsdlsoap:address location="http://localhost:8080/axis/services/StudentInfoService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

本文地址:http://com.8s8s.com/it/it41839.htm