`
xzs603
  • 浏览: 32175 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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的传输需要如何对它进行serializingde-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.jar7jar文件导入到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端说明要serializede-serializeJavaBean类别,参数的说明可参考axis api 文档。

要得到运行的结果,客户端这边需要得到Student.class文件,可是如果对于一个不在本机的服务,如何得到这个Student.class呢?——你需要阅读一下这个WebServicewsdl文档,里面有对这个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中支持的数据类型包含javaArrayList,所以用这个类型会方便很多。

 

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>

 

 

分享到:
评论

相关推荐

    h_JAVA 2应用编程150例.rar

    很多很好的一些例子. 第1章 Java图形用户界面编程 1 实例1 布局管理 2 实例2 设计软件启动界面 9 实例3 实现多色窗口 11 实例4 切分窗口 13 实例5 丰富多彩的按钮 15 ...实例150 构造Jsp/javabean开发和发布环境 537

    java应用软件程序设计

    这里边包括:第1章 Java图形用户界面编程 1 实例1 布局管理 2 实例2 设计软件启动界面 9 实例3 实现多色窗口 11 实例4 切分窗口 13 实例5 丰富多彩的按钮 15 实例6 在窗口中显示背景图 16 实例...

    JAVA上百实例源码以及开源项目源代码

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

    JAVA上百实例源码以及开源项目

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

    java 面试题 总结

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    Java EE常用框架.xmind

    4.PermissionsAuthorizationFilter 调用realm中的doGetAuthorizationInfo获取数据库中正确的权限 5.PermissionsAuthorizationFilter对item:query 和从realm中获取权限进行对比,如果“item:query”在realm...

    Java2核心技术.part5

    Java2核心技术第I卷.基础知识 目录: 译者序 ...5.7 远程方法调用与SOAP 第6章 高级Swing 第7章 高级AWT 第8章 JavaBean构件 第9章 安全 第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part3

    Java2核心技术第I卷.基础知识 目录: 译者序 ...5.7 远程方法调用与SOAP 第6章 高级Swing 第7章 高级AWT 第8章 JavaBean构件 第9章 安全 第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part1

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 ...5.7 远程方法调用与SOAP 第6章 高级Swing 第7章 高级AWT 第8章 JavaBean构件 第9章 安全 第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part6

    Java2核心技术第I卷.基础知识 目录: 译者序 ...5.7 远程方法调用与SOAP 第6章 高级Swing 第7章 高级AWT 第8章 JavaBean构件 第9章 安全 第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part4

    Java2核心技术第I卷.基础知识 目录: 译者序 ...5.7 远程方法调用与SOAP 第6章 高级Swing 第7章 高级AWT 第8章 JavaBean构件 第9章 安全 第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part2

    Java2核心技术第I卷.基础知识 目录: 译者序 ...5.7 远程方法调用与SOAP 第6章 高级Swing 第7章 高级AWT 第8章 JavaBean构件 第9章 安全 第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    超级有影响力霸气的Java面试题大全文档

    当客户机第一次调用一个Stateful Session Bean 时,容器必须立即在服务器中创建一个新的Bean实例,并关联到客户机上,以后此客户机调用Stateful Session Bean 的方法时容器会把调用分派到与此客户机相关联的Bean实例...

    J2EE应用开发详解

    218 12.1.3 RMI的优点 219 12.2 一个RMI的简单实例 219 12.3 小结 226 第13章 Web服务概论 227 13.1 SOA简介 227 13.2 Web服务简介 229 13.3 Web服务的核心技术 230 13.3.1 SOAP 232 13.3.2 WSDL 235 13.3.3 UDDI ...

    Spring中文帮助文档

    处理复杂类型的存储过程调用 12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring容器中创建 SessionFactory 12.2.3. The HibernateTemplate 12.2.4. 不使用回调的...

    Java面试宝典2010版

    72、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 73、字节流与字符流的区别 74、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。 ...

    最新Java面试宝典pdf版

    72、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 49 73、字节流与字符流的区别 50 74、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用...

Global site tag (gtag.js) - Google Analytics