真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

springboot實現(xiàn)切割分片上傳的方法

這篇文章給大家分享的是有關(guān)spring boot實現(xiàn)切割分片上傳的方法的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

從事四川聯(lián)通機房服務(wù)器托管,服務(wù)器租用,云主機,網(wǎng)站空間,域名注冊,CDN,網(wǎng)絡(luò)代維等服務(wù)。

文件上傳是web開發(fā)中經(jīng)常會遇到的

springboot的默認(rèn)配置為10MB,大于10M的是傳不上服務(wù)器的,需要修改默認(rèn)配置

但是如果修改支持大文件又會增加服務(wù)器的負(fù)擔(dān)。

當(dāng)文件大于一定程度時,不僅服務(wù)器會占用大量內(nèi)存,而且http傳輸極可能會中斷。

可以采用切割分片上傳

html5提供的文件API中可以輕松的對文件進(jìn)行分割切片,然后通過ajax異步處理向服務(wù)器傳輸數(shù)據(jù),突破對大文件上傳的限制,

同時異步處理在一定程度上也提高了文件上傳的效率。

過程描述:

  • 將文件分割成N片

  • 處理分片,前臺會多次調(diào)用上傳接口,每次都會上傳文件的一部分到服務(wù)端

  • N個分片都上傳完成后,將N個文件合并為一個文件,并將N個分片文件刪除

1.服務(wù)端

(1)添加依賴


   commons-fileupload
   commons-fileupload
   1.3.3

(2)UploadController

package com.example.demo.controller;

import com.example.demo.core.Result;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
@CrossOrigin
@Controller
@RequestMapping("/api/upload")
public class UploadController {
  @PostMapping("/part")
  @ResponseBody
  public Result bigFile(HttpServletRequest request, HttpServletResponse response, String guid, Integer chunk, MultipartFile file, Integer chunks) {
    try {
      String projectUrl = System.getProperty("user.dir").replaceAll("\\\\", "/");
      ;
      boolean isMultipart = ServletFileUpload.isMultipartContent(request);
      if (isMultipart) {
        if (chunk == null) chunk = 0;
        // 臨時目錄用來存放所有分片文件
        String tempFileDir = projectUrl + "/upload/" + guid;
        File parentFileDir = new File(tempFileDir);
        if (!parentFileDir.exists()) {
          parentFileDir.mkdirs();
        }
        // 分片處理時,前臺會多次調(diào)用上傳接口,每次都會上傳文件的一部分到后臺
        File tempPartFile = new File(parentFileDir, guid + "_" + chunk + ".part");
        FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);
      }

    } catch (Exception e) {
      return Result.failMessage(400,e.getMessage());
    }
    return Result.successMessage(200,"上次成功");
  }

  @RequestMapping("merge")
  @ResponseBody
  public Result mergeFile(String guid, String fileName) {
    // 得到 destTempFile 就是最終的文件
    String projectUrl = System.getProperty("user.dir").replaceAll("\\\\", "/");
    try {
      String sname = fileName.substring(fileName.lastIndexOf("."));
      //時間格式化格式
      Date currentTime = new Date();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
      //獲取當(dāng)前時間并作為時間戳
      String timeStamp = simpleDateFormat.format(currentTime);
      //拼接新的文件名
      String newName = timeStamp + sname;
      simpleDateFormat = new SimpleDateFormat("yyyyMM");
      String path = projectUrl + "/upload/";
      String tmp = simpleDateFormat.format(currentTime);
      File parentFileDir = new File(path + guid);
      if (parentFileDir.isDirectory()) {
        File destTempFile = new File(path + tmp, newName);
        if (!destTempFile.exists()) {
          //先得到文件的上級目錄,并創(chuàng)建上級目錄,在創(chuàng)建文件
          destTempFile.getParentFile().mkdir();
          try {
            destTempFile.createNewFile();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        for (int i = 0; i < parentFileDir.listFiles().length; i++) {
          File partFile = new File(parentFileDir, guid + "_" + i + ".part");
          FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);
          //遍歷"所有分片文件"到"最終文件"中
          FileUtils.copyFile(partFile, destTempfos);
          destTempfos.close();
        }
        // 刪除臨時目錄中的分片文件
        FileUtils.deleteDirectory(parentFileDir);
        return Result.successMessage(200,"合并成功");
      }else{
        return Result.failMessage(400,"沒找到目錄");
      }

    } catch (Exception e) {
      return Result.failMessage(400,e.getMessage());
    }

  }

}

說明:

注解 @CrossOrigin 解決跨域問題

(3)Result

package com.example.demo.core;

import com.alibaba.fastjson.JSON;

/**
 * Created by Beibei on 19/02/22
 * API響應(yīng)結(jié)果
 */
public class Result {
  private int code;
  private String message;
  private T data;

  public Result setCode(Integer code) {
    this.code = code;
    return this;
  }

  public int getCode() {
    return code;
  }

  public String getMessage() {
    return message;
  }

  public Result setMessage(String message) {
    this.message = message;
    return this;
  }

  public T getData() {
    return data;
  }

  public Result setData(T data) {
    this.data = data;
    return this;
  }

  @Override
  public String toString() {
    return JSON.toJSONString(this);
  }

  public static  Result fail(Integer code,T data) {
    Result ret = new Result();
    ret.setCode(code);
    ret.setData(data);
    return ret;
  }

  public static  Result failMessage(Integer code,String msg) {
    Result ret = new Result();
    ret.setCode(code);
    ret.setMessage(msg);
    return ret;
  }
  public static  Result successMessage(Integer code,String msg) {
    Result ret = new Result();
    ret.setCode(code);
    ret.setMessage(msg);
    return ret;
  }

  public static  Result success(Integer code,T data) {
    Result ret = new Result();
    ret.setCode(code);
    ret.setData(data);
    return ret;
  }

}

2.前端

(1)使用插件

webuploader,下載  https://github.com/fex-team/webuploader/releases




  
  
  
  


  
   
     選擇文件
     開始上傳    
  
var GUID = WebUploader.Base.guid();//一個GUID var uploader = WebUploader.create({   // swf文件路徑   swf: 'dist/Uploader.swf',   // 文件接收服務(wù)端。   server: 'http://localhost:8080/api/upload/part',   formData:{     guid : GUID   },   pick: '#picker',   chunked : true, // 分片處理   chunkSize : 1 * 1024 * 1024, // 每片1M,   chunkRetry : false,// 如果失敗,則不重試   threads : 1,// 上傳并發(fā)數(shù)。允許同時最大上傳進(jìn)程數(shù)。   resize: false }); $("#startBtn").click(function () {   uploader.upload(); }); //當(dāng)文件上傳成功時觸發(fā)。 uploader.on( "uploadSuccess", function( file ) {   $.post('http://localhost:8080/api/upload/merge', { guid: GUID, fileName: file.name}, function (data) {     if(data.code == 200){      alert('上傳成功!');     }    }); });

spring boot實現(xiàn)切割分片上傳的方法

(2)不使用插件

直接用HTML5的File API



  
    
    
    
  
  
    
      
        
        
          
                           開始上傳                        
        
                                    var status = 0;     var page = {     init: function(){       $("#startBtn").click($.proxy(this.upload, this));     },     upload: function(){       status = 0;       var GUID = this.guid();       var file = $("#file")[0].files[0], //文件對象         name = file.name,    //文件名         size = file.size;    //總大小       var shardSize = 20 * 1024 * 1024,  //以1MB為一個分片         shardCount = Math.ceil(size / shardSize); //總片數(shù)       for(var i = 0;i < shardCount;++i){         //計算每一片的起始與結(jié)束位置         var start = i * shardSize,         end = Math.min(size, start + shardSize);         var partFile = file.slice(start,end);         this.partUpload(GUID,partFile,name,shardCount,i);       }     },     partUpload:function(GUID,partFile,name,chunks,chunk){       //構(gòu)造一個表單,F(xiàn)ormData是HTML5新增的       var now = this;       var form = new FormData();       form.append("guid", GUID);       form.append("file", partFile); //slice方法用于切出文件的一部分       form.append("fileName", name);       form.append("chunks", chunks); //總片數(shù)       form.append("chunk", chunk);    //當(dāng)前是第幾片         //Ajax提交         $.ajax({           url: "http://localhost:8080/api/upload/part",           type: "POST",           data: form,           async: true,    //異步           processData: false, //很重要,告訴jquery不要對form進(jìn)行處理           contentType: false, //很重要,指定為false才能形成正確的Content-Type           success: function(data){             status++;             if(data.code == 200){               $("#output").html(status+ " / " + chunks);             }             if(status==chunks){               now.mergeFile(GUID,name);             }           }         });     },     mergeFile:function(GUID,name){       var formMerge = new FormData();       formMerge.append("guid", GUID);       formMerge.append("fileName", name);       $.ajax({         url: "http://localhost:8080/api/upload/merge",         type: "POST",         data: formMerge,         processData: false, //很重要,告訴jquery不要對form進(jìn)行處理         contentType: false, //很重要,指定為false才能形成正確的Content-Type         success: function(data){           if(data.code == 200){             alert('上傳成功!');           }         }       });     },     guid:function(prefix){         var counter = 0;         var guid = (+new Date()).toString( 32 ),           i = 0;         for ( ; i < 5; i++ ) {           guid += Math.floor( Math.random() * 65535 ).toString( 32 );         }         return (prefix || 'wu_') + guid + (counter++).toString( 32 );     }   };   $(function(){     page.init();   });   

spring boot實現(xiàn)切割分片上傳的方法

3.優(yōu)化 

springboot的默認(rèn)配置為10MB,前端分片改為20M時,就會報錯

org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (10486839) exceeds the configured maximum (10485760)

解決方法:

在 src/main/resources 下的 application.properties里添加

spring.servlet.multipart.max-file-size=30MB
spring.servlet.multipart.max-request-size=35MB

說明:

設(shè)置的數(shù)值雖好比前端傳過來的大,要不容易報錯

感謝各位的閱讀!關(guān)于“spring boot實現(xiàn)切割分片上傳的方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!


網(wǎng)站標(biāo)題:springboot實現(xiàn)切割分片上傳的方法
當(dāng)前URL:http://weahome.cn/article/jcghhi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部