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

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

          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, 0, 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.FileService 
    
        
        
    


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

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

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

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

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

      第三:在用wsdl2java命令生成stub类时,没有明白wsdl文件是哪一个,明明自己在service.xml中写明了,但是在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类会自动转换。

 

你可能感兴趣的:(Web,Service)