`

复合类型数据的传递

阅读更多
引用
文章出处:http://www.blogjava.net/nokiaguy/archive/2009/04/archive/2009/nokiaguy/archive/2009/nokiaguy/archive/2009/01/04/249805.html

        在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据,这些数据可以被称为复合类型的数据。数组与类(接口)是比较常用的复合类型。在Axis2中可以直接使用将WebService方法的参数或返回值类型声明成数组或类(接口)。但要注意,在定义数组类型时只能使用一维数组,如果想传递多维数组,可以使用分隔符进行分隔,如下面的代码所示:

String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国", "超人,蜘蛛侠,钢铁侠" } ;

上面的代码可以看作是一个3*3的二维数组。

        在传递类的对象实例时,除了直接将数组类型声明成相应的类或接口,也可以将对象实例进行序列化,也就是说,将一个对象实例转换成字节数组进行传递,然后接收方再进行反序列化,还原这个对象实例。

        下面的示例代码演示了如何传递数组与类(接口)类型的数据,并演示如何使用字节数组上传图像。本示例的客户端代码使用Java和C#编写。要完成这个例子需要如下几步:

一、实现服务端代码
ComplexTypeService是一个WebService类,该类的代码如下:
import java.io.FileOutputStream;
import data.DataForm;

public class ComplexTypeService
{
    //  上传图像,imageByte参数表示上传图像文件的字节,
    //  length参数表示图像文件的字节长度(该参数值可能小于imageByte的数组长度)
    public boolean uploadImageWithByte(byte[] imageByte, int length)
    {
        FileOutputStream fos = null;
        try
        {
            //  将上传的图像保存在D盘的test1.jpg文件中
            fos = new FileOutputStream("d:\\test1.jpg");
            //  开始写入图像文件的字节
            fos.write(imageByte, 0, length);
            fos.close();
        }
        catch (Exception e)
        {
            return false;
        }
        finally
        {
            if (fos != null)
            {
                try
                {
                    fos.close();
                }
                catch (Exception e)
                {

                }
            }
        }
        return true;
    }
    //  返回一维字符串数组
    public String[] getArray()
    {
        String[] strArray = new String[]{ "自行车", "飞机", "火箭" };
        return strArray;
    } 
    //  返回二维字符串数组
    public String[] getMDArray()
    {
        String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国", "超人,蜘蛛侠,钢铁侠" } ;
        return strArray;
    }
    //  返回DataForm类的对象实例
    public DataForm getDataForm()
    {
        return new DataForm();
    }
    //  将DataForm类的对象实例序列化,并返回序列化后的字节数组
    public byte[] getDataFormBytes() throws Exception 
    {
        java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
        java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);
        oos.writeObject(new DataForm());        
        return baos.toByteArray();
    }    
}


二、实现DataForm类
DataForm是要返回的对象实例所对应的类,该类的实现代码如下:
package data;

public class DataForm implements java.io.Serializable
{
    private String name = "bill";
    private int age = 20;

    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
}

三、发布WebService
        由于本示例的WebService类使用了一个Java类(DataForm类),因此,在发布WebService之前,需要先将DataForm.class文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\classes\data目录中,然后将ComplexTypeService.class文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中,最后启动Tomcat(如果Tomcat已经启动,由于增加了一个DataForm类,因此,需要重新启动Tomcat)。

四、使用Java编写调用WebService的客户端代码
在客户端仍然使用了RPC的调用方式,代码如下:
package pojo.client;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class ComplexTypeRPCClient
{

    public static void main(String[] args) throws Exception
    {
        RPCServiceClient serviceClient = new RPCServiceClient();
        Options options = serviceClient.getOptions();
        EndpointReference targetEPR = new EndpointReference(
                "http://localhost:8080/axis2/services/ComplexTypeService");
        options.setTo(targetEPR);
        // 下面的代码调用uploadImageWithByte方法上传图像文件
        /////////////////////////////////////////
        // 打开图像文件,确定图像文件的大小
        java.io.File file = new java.io.File("f:\\images.gif");
        java.io.FileInputStream fis = new java.io.FileInputStream("f:\\images.gif");
        // 创建保存要上传的图像文件内容的字节数组
        byte[] buffer = new byte[(int) file.length()];
        // 将图像文件的内容读取buffer数组中
        int n = fis.read(buffer);
        System.out.println("文件长度:" + file.length());
        Object[] opAddEntryArgs = new Object[]{ buffer, n };
        Class[] classes = new Class[]{ Boolean.class };
        QName opAddEntry = new QName("http://ws.apache.org/axis2","uploadImageWithByte");
        fis.close();
        // 开始上传图像文件,并输出uploadImageWithByte方法的返回传
        System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);
        /////////////////////////////////////////
        
        // 下面的代码调用了getArray方法,并返回一维String数组
        /////////////////////////////////////////  
        opAddEntry = new QName("http://ws.apache.org/axis2", "getArray");
        String[] strArray = (String[]) serviceClient.invokeBlocking(opAddEntry, 
                            new Object[]{}, new Class[]{String[].class })[0];
        for (String s : strArray)
            System.out.print(s + "  ");
        System.out.println();
        ///////////////////////////////////////// 
        

        // 下面的代码调用了getMDArray方法,并返回一维String数组
        /////////////////////////////////////////  
        opAddEntry = new QName("http://ws.apache.org/axis2", "getMDArray");
        strArray = (String[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{}, 
                                                          new Class[]{String[].class})[0];
        for (String s : strArray)
        {
            String[] array = s.split(",");
            for(String ss: array)
                System.out.print("<" + ss + "> ");
            System.out.println();
        }
        System.out.println();
        ///////////////////////////////////////// 

        // 下面的代码调用了getDataForm方法,并返回DataForm对象实例
        /////////////////////////////////////////  
        opAddEntry = new QName("http://ws.apache.org/axis2", "getDataForm");
        data.DataForm df = (data.DataForm) serviceClient.invokeBlocking(opAddEntry, new Object[]{},
                                                                  new Class[]{data.DataForm.class})[0];
        System.out.println(df.getAge());
        /////////////////////////////////////////
        
        // 下面的代码调用了getDataFormBytes方法,并返回字节数组,最后将返回的字节数组反序列化后,转换成DataForm对象实例
        /////////////////////////////////////////          
        opAddEntry = new QName("http://ws.apache.org/axis2", "getDataFormBytes");
        buffer = (byte[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{}, new Class[]{byte[].class})[0];
        java.io.ObjectInputStream ois = new java.io.ObjectInputStream(
                new java.io.ByteArrayInputStream(buffer));
        df = (data.DataForm) ois.readObject();
        System.out.println(df.getName());
        //////////////////////////////////////////
    }
}

运行上面的程序,将输出如下的内容:
引用
文件长度:97813
true
自行车  飞机  火箭 
<自行车> <飞机> <火箭>
<中国> <美国> <德国>
<超人> <蜘蛛侠> <钢铁侠>

20
bill




分享到:
评论

相关推荐

    axis2实现WebService之复合类型数据的传递.doc编程资料

    axis2实现WebService之复合类型数据的传递.doc

    全面探讨PL SQL的复合数据类型

    在PL/SQL编程中,复合数据类型是处理复杂数据结构的关键工具,主要包含记录(Record)和集合(Collection)。本文将深入探讨这两种数据结构,帮助读者理解和应用它们。 首先,让我们来了解一下PL/SQL的记录(Record...

    WebService大讲堂之Axis2(2):复合类型数据的传递.pdf

    总结,本篇内容主要讲解了如何在 Axis2 中处理复合类型数据的传递,包括数组(一维和二维)以及自定义类对象。通过 Axis2,开发者可以直接使用 Java 类型作为 WebService 方法的参数和返回值,简化了开发过程。同时...

    2.1.3 C++和C#数据传递 -struct类型传递

    本节我们将探讨“2.1.3 C++和C#数据传递 - struct类型传递”这个主题,深入理解这两种语言在结构体(struct)类型数据传递上的特点。 首先,让我们定义什么是结构体。结构体是一种自定义的数据类型,它允许我们把多...

    Intent数据传递实用方法

    本篇文章将深入探讨如何利用Intent进行数据传递,并以Activity间的交互为例,详细阐述相关实用方法。 首先,Intent分为显式Intent和隐式Intent两种类型。显式Intent通过指定目标组件的全类名来启动特定的Activity或...

    轻松学C之复合数据类型优秀PPT.pptx

    在编程语言C++中,复合数据类型是为了解决基本数据类型无法满足复杂数据结构需求的问题而引入的。这些复合数据类型包括结构体(struct)、联合(union)、枚举(enumeration)以及用户自定义数据类型。本篇主要讨论...

    GO语言 复合类型专题

    总结来说,GO语言中的复合类型提供了丰富的数据结构选择,如结构体用于组合多种类型的数据,结构体指针用于高效地传递和操作结构体,数组提供固定长度的序列,而切片则提供了灵活的、可变长度的序列,适用于各种编程...

    节 复合数据类型PPT学习教案.pptx

    6. **数据传递**: - **函数参数**:结构体可以通过值传递(实参复制给形参,效率低)、指针传递(传递指针,效率高)或返回值方式在函数之间传递。 理解这些复合数据类型及其用法是成为熟练的C程序员的关键步骤。...

    第11讲-复合数据类型3教学课件PPT文档.pptx

    在本讲中,我们将重点讨论【指针】以及如何使用它们操作【结构体类型数据】。 【指针】在C语言中扮演着至关重要的角色,它是一种变量,存储了另一个变量的地址。当我们谈论【指向结构体类型数据的指针】时,意味着...

    易语言自定义数据类型的内存存储方式

    需要注意的是,易语言中的自定义数据类型在内存中是以值传递的方式进行操作的,这意味着当你将一个自定义数据类型的变量赋值给另一个变量时,实际上是复制了整个数据结构的内容,而不是引用。这种机制在处理大量数据...

    火山PC类似易语言的自定义数据类型结构体案例

    结构体是一种复合数据类型,它可以包含多个不同类型的成员,通过一个标识符(结构体名)来引用。 首先,我们需要了解如何在火山PC中定义一个结构体。这通常通过声明一个新的类型并指定其成员来完成。例如,如果我们...

    07.处理Map等CXF无法自动转换的复合数据类型的形参和返回值

    本文将详细探讨如何处理Map等CXF无法自动转换的复合数据类型的形参和返回值,这对于提升服务功能和用户体验至关重要。 首先,我们需要理解CXF的工作原理。CXF提供了一种直观的方式来创建和消费Web服务,它通过Java...

    混合计算工程中复合数据的传递 (Ⅲ)―――派生类型内嵌数组 (2009年)

    当前的大型水利信息系统工程建设中,迫切需要解决内嵌数组派生类型这一特殊结构的复合数据的传递问 题。对此,从不同集成开发环境提供的 OLE自动化扩展功能出发,利用独立于具体语言的安全数组,对内嵌数组的 派生类型...

    西门子 S7-300的数据类型.doc

    西门子 S7-300 数据类型 西门子 S7-300 的数据类型可以分为三种:基本数据类型、复合数据类型和参数类型。...参数类型是为在逻辑块之间传递参数的形参(FormalParameter,形式参数)定义的数据类型。

    易语言自定义数据类型访问提速

    首先,自定义数据类型(也称为结构体或类)是将多个不同类型的变量组合在一起形成一个新的复合类型。在易语言中,你可以定义包含整型、浮点型、字符串等多种类型的结构体,并对其进行操作。定义自定义数据类型的基本...

    数据类型的分类

    在"数据类型的分类"这个主题中,我们不仅探讨了基本数据类型,还深入到了结构体这一复合数据类型。通过学习和理解这些内容,开发者可以更加有效地组织和管理代码,实现更复杂的程序设计。而提供的"C++语言入门基础...

    易语言DLL返回自定义数据类型源码.zip

    1. **自定义数据类型**:在易语言中,自定义数据类型允许开发者创建新的复合数据结构,例如包含不同类型变量的结构。这可以通过"定义数据类型"命令来实现,如定义一个包含整型、浮点型和字符串的结构体。 2. **DLL...

    数据类型检查基础知识.pptx

    复合数据类型扩展了基本类型,如字符串、指针、文件等,提供了更复杂的数据结构。用户定义的数据类型允许创建结构化数据,如包含多个成员的结构体,其操作包括成员选择、插入、删除等。抽象数据类型进一步强化了这一...

Global site tag (gtag.js) - Google Analytics