加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

axis2开发webservice之(二进制文件传输)

发布时间:2020-12-17 00:32:56 所属栏目:安全 来源:网络整理
导读:????????? 本来今天的程序应该是最简单的,因为涉及到的流程在上周已经学会了,不同的地方只有代码部分了。但是自己还是大意了,现在总结一下。 ????????? WebService 类中包含 byte[] 类型参数的方法在 wsdl2java 生成的 stub 类中对应的数据类型不再是 byt

????????? 本来今天的程序应该是最简单的,因为涉及到的流程在上周已经学会了,不同的地方只有代码部分了。但是自己还是大意了,现在总结一下。

????????? WebService类中包含byte[]类型参数的方法在wsdl2java生成的stub类中对应的数据类型不再是byte[]类型,而是javax.activation.DataHandlerDataHandler类是专门用来映射WebService二进制类型的。
???????
WebService类中除了可以使用byte[]作为传输二进制的数据类型外,也可以使用javax.activation.DataHandler作为数据类型。不管是使用byte[],还是使用javax.activation.DataHandler作为WebService方法的数据类型,使用wsdl2java命令生成的stub类中相应方法的类型都是javax.activation.DataHandler。而象使用.netdelphi生成的stub类的相应方法类型都是byte[]。这是由于javax.activation.DataHandler类是Java特有的,对于其他语言和技术来说,并不认识javax.activation.DataHandler类,因此,也只有使用最原始的byte[]了。

??????? 看到这段话的时候,我才知道了为什么在复杂数据类型传递中,我会无缘无故的碰到DataHandler。??????

?????? 下面是一个上传二进制文件的例子,WebService类的代码如下:
???????

package binary;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import javax.activation.DataHandler;

public class FileService {
	// 使用byte[]类型参数上传二进制文件
	public boolean uploadWithByte(byte[] file,String filename) {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(filename);
			fos.write(file);
			fos.close();
		} catch (Exception e) {
			return false;
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (Exception e) {
				}
			}
		}
		return true;
	}

	private void writeInputStreamToFile(InputStream is,OutputStream os)
			throws Exception {
		int n = 0;
		byte[] buffer = new byte[8192];
		while ((n = is.read(buffer)) > 0) {
			os.write(buffer,n);
		}
	}

	// 使用DataHandler类型参数上传文件
	public boolean uploadWithDataHandler(DataHandler file,String filename) {

		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(filename);
			// 可通过DataHandler类的getInputStream方法读取上传数据
			writeInputStreamToFile(file.getInputStream(),fos);
			fos.close();
		} catch (Exception e) {
			return false;
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (Exception e) {
				}
			}
		}
		return true;
	}
}

上面代码在services.xml文件的配置代码如下:

<service name="fileService">
    <description>
        文件服务
    </description>
    <parameter name="ServiceClass">
        service.FileService 
    </parameter>
        <messageReceivers>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    </messageReceivers>
</service>


???? 接下来的事情就好办了,跟之前一样,生成.aar文件和stub类。但是正所谓“家贼难防”,我们往往是死在自己熟悉的人手里的,哈哈,开个玩笑。

??? 在这个地方我至少犯了三个错误:

??? 第一:在生成.aar文件的时候,太机械了,直接用上次的模板,连包名都没有改,上次的是service包,但是这次的是binary包,肯定不一样,生成的aar文件放到tomcat下面不报错才怪呢

???? 第二:刚把包名解决掉,可是又把文件的后缀名写错,直接生成了.arr包,放到tomcat下面之后,tomcat直接不鸟他,然后有些人还大言不惭的再百度里搜“tomcat不识别.arr文件”,坑爹啊,百度里居然有相关的内容,这更是延长路了我找出这个错误的时间。哈哈,现在想来真他妈的搞笑。

???? 这两个问题说白了就是下面的这张图

???? ?第三:在用wsdl2java命令生成stub类时,没有明白wsdl文件是哪一个,明明自己在service.xml中写明了<service name="fileService">,但是在wsdl2java命令中却仍然是用pojo类名,还说“昨天不是好好的吗”(哈哈,程序员的经典口头禅),难道你不知道昨天你把pojo的类名和wsdl文件名(也就是xml中的name属性)写成了一样的吗,今天不一样了,你难道就不知道变通一下吗。哈哈,太坑爹了。

??? 就这三个问题一起出现,排列组合太多,搞得我浪费了两个小时,坑死哥了。

??

如果使用wsdl2java命令生成调用Java客户端代码,则需要创建DataHandler类的对象实例,代码如下:

DataHandler?dh?=?new?DataHandler(new?FileDataSource(imagePath));

wsdl2java命令会为每一个方法生成一个封装方法参数的类,类名为方法名(第一个字符大写),如uploadWithByte方法生成的类名为UploadWithByte。如果要设置file参数的值,可以使用UploadWithByte类的setFile方法,代码如下:

UploadWithByte?uwb?=?new?UPloadWithByte();
uwb.setFile(dh);

?

最后是调用uploadWithByte方法,代码如下(FileServiceStubwsdl2java生成的stub类名):

FileServiceStub?fss?=?new?FileServiceStub();
fss.uploadWithByte(uwb);

?

下面是完整的客户端代码

package binary;

import java.rmi.RemoteException;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;

import binary.FileServiceStub.UploadWithByteResponse;

public class FileStubClient {

	public static void main(String[] args) throws RemoteException {
		FileServiceStub fss = new FileServiceStub();
		FileServiceStub.UploadWithByte uwb = new FileServiceStub.UploadWithByte();
		DataHandler dh = new DataHandler(new FileDataSource("f:images.jpg"));
		uwb.setFile(dh);
		uwb.setFilename("byte上传");
		fss.uploadWithByte(uwb);
		System.out.println("byte上传?"+uwb.isFileSpecified()+"   "+"名字有无命名:"+uwb.isFilenameSpecified());
		
		FileServiceStub.UploadWithDataHandler uwdh = new FileServiceStub.UploadWithDataHandler();
		uwdh.setFile(dh);
		//uwdh.setFilename("DataHandler上传");
		fss.uploadWithDataHandler(uwdh);
		System.out.println("DataHandler上传?"+uwdh.isFileSpecified()+"   "+"名字有无命名:"+uwdh.isFilenameSpecified());
	}

}


运行结果:

???

???? 与上次的复杂数据类型传递相比,这次的简单多了,不需要byte和DataHandler之间的人工转换,stub类会自动转换。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读