base64图片打成Zip包上传,以及服务端解压的简单实现

1、前言

上传图片一般采用异步上传的方式,但是异步上传带来不好的地方,就如果图片有改变或者删除,图片服务器端就会造成浪费。所以有时候就会和参数同步提交。笔者喜欢base64图片一起上传,但是图片过多时就会出现数据丢失等异常。因为tomcat的post请求默认是2M的长度限制。

2、解决办法

有两种:

①    修改tomcat的servel.xml的配置文件,设置 maxPostSize=“-1”,来取消post请求参数的限制

②    图片压缩层Zip文件,作为一个文件上传。(今天记录一下后者的简单编写)

3、依赖坐标

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant</artifactId>
    <version>1.9.4</version>
</dependency>

这个依赖有点“重”,也可以选择其他第三方插件

4、上代码

@RequestMapping("/upload")
@ResponseBody
public JsonResult upload(@RequestParam("zipFile")MultipartFile zipFile) throws IOException{
    // 获取上传的文件
    CommonsMultipartFile  commonsMultipartFile = (CommonsMultipartFile)zipFile;
    // 将CommonsMultipartFile转化成java.io.File。  这里转化还可以使用tranferTo方法
    DiskFileItem fileItem = (DiskFileItem)commonsMultipartFile.getFileItem();
    File file = fileItem.getStoreLocation();
				
    // 这里的ZipFile为: org.apache.tools.zip.ZipFile   jdk自带的ZipFile没有getEntries方法
    ZipFile zipFile = new ZipFile(file);
    Enumeration<ZipEntry> entries = zipFile.getEntries();
    while(entries.hasMoreElements()){
        ZipEntry zipEntry = entries.nextElement();
        InputStream is = zipFile.getInputStream(zipEntry);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        // 使用IOUtils工具类
        org.apache.commons.io.IOUtils.copy(is, bos);
        is.close();
        bos.close();
        // 文件上传
        String uploadFile = dfsService.uploadFile(bos.toByteArray(), zipEntry.getName());
        System.out.println(uploadFile);
    }
    return new JsonResult(true);
}

本文值只做了简单的实现,实际应用需要多种校验。

5、前端页面压缩的代码

      使用zip包上传是为了减少传输的数量,这里使用jsZip这个前端工具实现打包,最终以二进制流的方式上传。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>测试JSZIP</title>
</head>
<body>
    <input type="file" id="file" />
    <img src="" id="image">
</body>
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/jszip.js"></script>
<script type="text/javascript">
$(function(){
    $("#file").change(function(){
        var file = this.files[0];
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(){
            // 获取base64图片
            var imgData = this.result;
            // 取消base64图片的标识
            var base64 = imgData.substring(imgData.indexOf(",")+1);
            // 使用JSZip打包
            var zip = new JSZip();
            zip.file("car.jpg", base64, {base64: true});
            zip.file("car2.jpg", base64, {base64: true});
            zip.file("car3.jpg", base64, {base64: true});
            zip.generateAsync({type:"blob"}).then(function(content) {
                var formData = new FormData();
                // content 为二进制流的形式,后台接收的类型为:application/zip
                formData.append("zipFile", content);
                $.ajax({
                    url:"http://127.0.0.1/upload",
                    type:"POST",
                    data:formData,
                    processData: false, //processData 默认为false,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
                    contentType: false,
                    success:function(){
                        alert("上传成功!")
                    }
                });
            });
        }
    });
});

6、注意事项

  • 单张图片上传,ajax使用FormData以Blob或者File(Blob的更具体的实现)的形式,上传的时候会以binary(二进制字节流)的形式上传,使用MultipartFile对象接收,没有问题。
  • 如果多张图片使用Blob[]上传,传递的参数会你变成[Object blob],后台无法使用MultipartFile接收参数,使用时注意!

7、参考文档

jsZip官方文档:https://stuk.github.io/jszip/

-- END

猜你喜欢

转载自blog.csdn.net/static_coder/article/details/84142870