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

在实际的应用中,不仅需要使用WebService来传递简单类型的数据,有时也需要传递更复杂的数据,这些数据可以被称为复合类型的数据。数组与类(接口)是比较常用的复合类型。在Axis2中可以直接使用将WebService方法的参数或返回值类型声明成数组或类(接口)。但要注意,在定义数组类型时只能使用一维数组,如果想传递多维数组,可以使用分隔符进行分隔,如下面的代码所示:
String[] strArray = new String[]{ "自行车,飞机,火箭","中国,美国,德国", "超人,蜘蛛侠,钢铁侠" } ;
上面的代码可以看作是一个3*3的二维数组。
在传递类的对象实例时,除了直接将数组类型声明成相应的类或接口,也可以将对象实例进行序列化,也就是说,将一个对象实例转换成字节数组进行传递,然后接收方再进行反序列化,还原这个对象实例。
下面的示例代码演示了如何传递数组与类(接口)类型的数据,并演示如何使用字节数组上传图像。本示例的客户端代码使用JavaC#编写。要完成这个例子需要如下几步:

一、实现服务端代码

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 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.jpg");
        java.io.FileInputStream fis 
= new java.io.FileInputStream("f:\\images.jpg");
        
// 创建保存要上传的图像文件内容的字节数组
        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());
        
//
    }
}
运行上面的程序,将输出如下的内容:
文件长度:3617

true

自行车 飞机 火箭 

<自行车> <飞机> <火箭>

<中国> <美国> <德国>

<超人> <蜘蛛侠> <钢铁侠>

20

bill
五、使用C#编写调用WebService的客户端代码
Visual Studio中使用WebService就简单得多。假设引用WebService时的引用名为complexType,则下面的代码调用了uploadImageWithByte方法来上传图像文件。在Visual Studio引用WebService时,uploadImageWithByte方法多了两个out参数,在使用时要注意。

complexType.ComplexTypeService cts = new WSC.complexType.ComplexTypeService();
System.IO.FileStream fs 
= new System.IO.FileStream(@"f:\images.jpg", System.IO.FileMode.Open);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 
0, (int)fs.Length);
bool r;
bool rs;
cts.uploadImageWithByte( buffer, (
int)fs.Length, trueout r, out rs);
在获得二维数组时,可以将数据加载到DataGridView或其他类似的控件中,代码如下:
String[] strArray = cts.getMDArray();
for (int i = 0; i < strArray.Length; i++)
{
    
//  用正则表达式将带分隔符的字符串转换成String数组
    String[] columns = strArray[i].Split(',');
    
//  如果DataGridView的表头不存在,向DataGridView控件添加三个带表头的列
    if (dataGridView1.Columns.Count == 0)
        
for (int j = 0; j < columns.Length; j++)
            dataGridView1.Columns.Add(
"column" + (j + 1).ToString(), "" + (j + 1).ToString());
    
//  添加行
    dataGridView1.Rows.Add(1);
    
for(int j = 0; j < columns.Length; j++)
    {
        dataGridView1.Rows[i].Cells[j].Value 
= columns[j];                       
    }                
}
DataGridView控件添加数据后的效果如图1所示。



图1 
对于其他的WebService方法的调用都非常简单,读者可以自己做这个实验。
要注意的是,由于.netjava序列化和反序列化的差异,通过序列化的方式传递对象实例只使用于客户端与服务端为同一种语言或技术的情况,如客户端和服务端都使用Java来编写。
    如果读者要上传大文件,应尽量使用FTP的方式来传递,而只通过WebService方法来传递文件名等信息。这样有助于提高传输效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux虚拟摄像头vivid配置

总述最近在看摄像头驱动&#xff0c;需要配置虚拟摄像头的驱动&#xff0c;但是教程里面是linux2.6内核的&#xff0c;实际电脑的是Ubuntu16&#xff0c;内核是linux4.15版本&#xff0c;从2.6到4.15内核好多文件发生了变化&#xff0c;所以我们该怎么操作呢&#xff1f;下面就…

第一次工作报告

要求 1. 对源文件&#xff08;*.txt,*.cpp,*.h,*.cs,*.html,*.js,*.java,*.py,*.php等&#xff09;统计字符数、单词数、行数、词频&#xff0c;统计结果以指定格式输出到默认文件中&#xff0c;以及其他扩展功能&#xff0c;并能够快速地处理多个文件。 2. 使用性能…

TQ210——S5PV210 uboot顶层mkconfig分析

################################################################################################# # SHELL常用内部参数&#xff1a;   # $# —— 传递给程序的总的参数数目 # $? —— 上一个代码或者shell程序在shell中退出的情况&#xff0c;如果正常退出则返回0&am…

音频系统底层API

IAudioEndpointVolume IAudioEndpointVolume接口表示进出音频端点设备的音频流的音量控制。 客户端通过调用参数iid设置为REFIID IID_IAudioEndpointVolume的IMMDevice :: Activate方法获取对端点设备的IAudioEndpointVolume接口的引用。 IAudioEndpointVolume编程调节Win7/Wi…

早睡早起

这两天考虑着以前工作的一些问题。有一点非常需要改正。就是作息时间不规律。经常睡的很晚。把前两年锻炼身体的老本吃的差不多了。该是“存钱”的时候了。新的工作依旧很繁忙&#xff0c;事情很多&#xff0c;但是身体调整绝对不能放松的。所以还是决定从明天开始早起&#xf…

树莓派Pico的一些有趣的基本实验

▲ 实验电路板Raspberry PI Pico小型MCU模块&#xff0c;以其价格低廉&#xff0c;功能丰富&#xff0c;开发方便为很多非电子类专业的同学进行创意项目原型设计提供了方便的平台。下面的一些实验给CDIE课程设计同学们制作的一些基本演示实验。▌01 PI Pico实验板在 RASPBERRY …

Gabor变换

gabor变换分析非平稳信号有弊端主要是时频窗宽度固定 小波wavelet a小窗窄a大窗宽 窗口或短时傅氏变换在时域上和频域上的局部化程度主要由窗函数g(x)的有效时宽Δt 和有效带宽Δf 决定。Δt 和Δf 越小, 表明局部性越好。但Heisenberg 测不准原理指出[ 6] :Δt 和Δf 不可能任…

30块钱的树莓派跑unix系统,源码全部开源,香

▌ 1、前言之前做活动抽奖送的几个树莓派&#xff0c;但是因为好几个人都没有填写地址&#xff0c;所以就只能把东西寄回来给我&#xff0c;然后手痒自己玩了下&#xff0c;觉得这个东西确实很香&#xff0c;比一般的Linux开发板都好。PICO这个开发板可以玩很多东西1 、运行pic…

CoInitialize\CoCreateGuid\CoCreateInstance

CoInitialize是Windows提供的API函数&#xff0c;用来告诉 Windows以单线程的方式创建com对象。应用程序调用com库函数&#xff08;除CoGetMalloc和内存分配函数&#xff09;之前必须初始化com库。 https://baike.baidu.com/item/CoInitialize/4114580?fraladdin CoCreateGui…

产品设计体会(8001)产品经理工作手册

产品经理的工作是最具挑战性的工作之一。产品经理职责描述产品经理的全部责任在于通过了解不断变化的市场需求和优化产品推向目标市场的全过程&#xff0c;将企业的不同组成部分凝聚成一个战略上一致集中的整体&#xff0c;同时将一项产品的价值最大化。产品经理的全部职责在于…

Oracle11gR2_ADG管理之恢复主库的truncate表实战

备库开启flashback database #关闭备库的同步 SQL> alter database recover managed standby database cancel;Database altered.SQL> select flashback_on from v$database;FLASHBACK_ON ------------------ NOSQL> alter database flashback on;Database altered.SQ…

为什么大家都只谈薪资,却不谈梦想?

说个薪资的问题&#xff0c;最近在帮一个朋友物色工作&#xff0c;当然&#xff0c;除了我那个朋友以外&#xff0c;也有挺多同学向我咨询offer薪资的问题。先说我那个朋友。高中毕业后去当兵&#xff0c;服兵役结束后去4s店修车&#xff0c;我车子的很多问题也会向他咨询&…

获取指定地址的值

C语言 —— 获取指定地址的值 int b *((volatile unsigned int *)0x0028FF1C);// 0x0028FF1C就是内存中的地址&#xff0c;根据自己需要指定 #include <stdio.h> #include <stdlib.h>int main() {int b *((volatile unsigned int *)0x0028FF1C);printf("b…

IAudioEndpointVolume

IAudioEndpointVolume https://docs.microsoft.com/en-us/windows/desktop/api/endpointvolume/nf-endpointvolume-iaudioendpointvolume-setmute

DataTable.Compute功能

DataTable.Compute具有这么多的功能 1&#xff1a;聚合函数”Sum()” 2&#xff1a;自由计算表达式“20*301” 3&#xff1a;bool表达式“12” 4&#xff1a;IFF逻辑表达式” IIF(20>1000, 0, 1)” //还支持IsNull&#xff0c;Trim&#xff0c;SubString等 一个小应用&#…

Linux下查看内存使用情况方法总结

Linux下查看内存使用情况方法总结转载于:https://www.cnblogs.com/cdyboke/p/8689270.html

差生的 8 年程序员总结

今年终于从大菊花厂离职了&#xff0c;离职前收入大概60w不到吧&#xff0c;在某乎属于比较差的&#xff0c;今天终于有空写一下自己的职场故事&#xff0c;也算是给自己近8年的程序员工作做个总结复盘。近8年有些事情做对了&#xff0c;也有更多事情做错了&#xff0c;在这里记…

关闭windows垃圾服务

Windows集成了许多功能和服务&#xff0c;所以在很多领域得以应用&#xff1b;但是有很多服务是我们个人用户所用不到的&#xff0c;开启只会浪费内存和资源&#xff0c;并且成为***和病毒***的靶子&#xff0c;而且&#xff0c;还影响启动速度和运行速度。关掉大部分没用的服务…

Python简单的抓取静态网页内容

import requests from bs4 import BeautifulSoup res requests.get(http://news.sina.com.cn/china/)#获取目标网页 res.encoding utf-8#抓取网页出现乱码 #print(res.text) soup BeautifulSoup(res.text,html.parser)#爬取网页 for news in soup.select(.news-item): if le…