webservice(axis)接口上传文件附件 及 用zlib解压缩
webservice传文件,我平时用到的webservice框架也就是Axis和CXF,这两种框架都可以用DataHandler进行文件的传输,这种的传的是文件的内容,不会有文件名称,类型,所以这些得自己在接口中加字段;还有一种方式就是将文件转化成字节数组,再用Base64将字节数组编码成字符串类型放入接口字段中进行传输,接受的一方先解码然后存文件。
目前用到的就是后一种,无论前一种还是后一种,两种方式传输的文件都不能太大,前一种具体能传多大不太清楚,后一种十几兆或者二十多兆还是可以传的,只是传输的比较慢,而且接受端要延长超时时间。
关于压缩,目前只在测试环境试了下,而且不知道是不是因为zlib对pdf的压缩是不是不友好,压缩pdf的文件压缩率比较低,我测了下A方压缩后传过来的文件,解压前和解压后差的不太多,压缩率为6%,也就是说10M的只压缩到了9.4M,压不压缩也没什么区别了,因为这次上线时间紧,所以其他的压缩方法也没有来的急试,这次记录就先记录下zlib的压缩/解压缩。
这次顺便也复习了下文件读写的过程,关于输入输出流这位老哥说的挺全的https://blog.csdn.net/msk_zn/article/details/73385467。
一. DataHandler进行文件传输
1.Axis框架
2.CXF框架
注:用这两个框架的DataHandler方式上传文件暂时先不整理,因为暂时没有这方面的需求,所以靠后放放,有时间了补上:)。
二. 编码后传输
1.发送端
发送端要做的就是把文件读取成输入流,然后将输入流读取写入到输出流,然后将输出流转化为字节数组,用Base64编码成String字符串类型的对象,将这个字符串对象放入接口对应的字段中发送就ok了;
1 InputStream in = new FileInputStream(filePath); 2 ByteArrayOutputStream out = new ByteArrayOutputStream(); 3 byte[] buffer = new byte[1024]; 4 int n = 0; 5 while ((n = in.read(buffer)) != -1) { 6 out.write(buffer, 0, n); 7 } 8 byte[] data = out.toByteArray(); 9 in.close(); 10 11 BASE64Encoder encoder = new BASE64Encoder();//Base64编码方式很多,自行挑选,注意编码解码用同一种即可。 12 String encodedText = encoder.encode(textByte);
2.接收端
接受端所做的和发送端相反,先将接受到的字符串对象先用Base64解码成字节数组,然后将字节数组转变为字节数组输入流,存入文件;
1 String content = "发送端传过来的内容"; 2 File destfile = new File("想要存储文件的路径+名称"); 3 4 BASE64Decoder decoder = new BASE64Decoder();//Base64解码方式较多,自行挑选,注意编码解码用同一种即可。 5 byte[] bytes = decoder.decodeBuffer(content); 6 InputStream is = new ByteArrayInputStream(bytes); 7 byte[] buff = new byte[1024]; 8 int len = 0; 9 FileOutputStream fos = new FileOutputStream(destfile); 10 bos = new BufferedOutputStream(fos); 11 while((len=is.read(buff))!=-1){ 12 fos.write(buff, 0, len); 13 } 14 is.close(); 15 fos.close();
三.压缩后传输
本次记录的压缩方法是Zlib,因为项目中用到了所以记录下。网上关于Zlib介绍的文章不少,但是大都千篇一律,来源都是这位老哥的 https://www.iteye.com/blog/snowolf-465433 ,文章中不仅记录了Zlib的压缩和解压缩,还记录了zip的压缩解压缩,Linux下的压缩格式Gzip,BZip2的压缩解压缩,写的很详细,很棒。
1.Zlib的压缩
Zlib压缩的方法有两种,一种是对字节数组进行压缩,另一种是对输出流进行压缩。
2.Zlib的解压缩
解压缩同理,可以对字节数组进行解压缩,也可以对输入进行解压缩。
1 byte[] bytes = decoder.decodeBuffer(content); 2 File file=new File(filePath+"/"+fileName); 3 FileOutputStream fos = new java.io.FileOutputStream(file); 4 BufferedOutputStream bos = new BufferedOutputStream(fos); 5 6 //输入流形式进行解压缩 7 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); 8 InflaterInputStream iis = new InflaterInputStream(byteArrayInputStream); 9 int i = 1024; 10 Integer sum = 0; 11 byte[] buf = new byte[i]; 12 while ((i = iis.read(buf, 0, i)) > 0) { 13 bos.write(buf, 0, i); 14 15 } 16 iis.close; 17 bos.close;
1 byte[] bytes = decoder.decodeBuffer(content); 2 File file=new File(filePath+"/"+fileName); 3 FileOutputStream fos = new java.io.FileOutputStream(file); 4 BufferedOutputStream bos = new BufferedOutputStream(fos); 5 6 //字节数组形式解压缩 7 Inflater decompresser = new Inflater(); 8 decompresser.reset(); 9 decompresser.setInput(bytes); 10 byte[] buf = new byte[1024]; 11 while (!decompresser.finished()) { 12 int i = decompresser.inflate(buf); 13 bos.write(buf, 0, i); 14 } 15 bos.close; 16 fos.close;
3.zip的压缩
4.zip的解压缩
注:zip的压缩解压缩暂时没用到,但是在测试的时候也用到了一点,有时间后整理:)。
最后,对于压缩后Base64编码传输的可以参考以上两种方式,先对传输内容进行解码,然后解压缩。好像留的坑挺多,但是基本功能可以实现,等什么时候把内容补全了,再修改文章的标题!
相关文章:
java-文件流正确关闭资源 https://www.cnblogs.com/tfper/p/9833722.html (上文中的文件流关闭并不严谨,关于正确关闭文件流可参考这篇文章)
Java压缩技术 https://www.iteye.com/blog/snowolf-465433
java-将字符串或者字节数组等,转换为输入流 https://blog.csdn.net/y41992910/article/details/80176552
Java输入输出流详解 https://blog.csdn.net/msk_zn/article/details/73385467