spring boot 는 어떻게 절단 블록 업 로드 를 실현 합 니까?
파일 업 로드 는 웹 개발 에서 자주 볼 수 있 는 것 입 니 다.
springboot 의 기본 설정 은 10MB 이 고 10M 이상 은 서버 에 전송 되 지 않 습 니 다.기본 설정 을 수정 해 야 합 니 다.
하지만 지원 하 는 큰 파일 을 수정 하면 서버 의 부담 이 커진다.
파일 이 어느 정도 크 면 서버 가 대량의 메모 리 를 차지 할 뿐만 아니 라 http 전송 이 중 단 될 수 있 습 니 다.
절단 편 으로 업로드 할 수 있 습 니 다.
html 5 에서 제공 하 는 파일 API 에서 파일 을 쉽게 분할 하여 자 른 다음 ajax 비동기 처 리 를 통 해 서버 에 데 이 터 를 전송 하여 큰 파일 업로드 에 대한 제한 을 돌파 할 수 있 습 니 다.
이 동시에 비동기 처 리 는 어느 정도 파일 업로드 의 효율 을 높 였 다.
프로 세 스 설명:
(1)의존 도 추가
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
(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();
}
// , ,
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");
//
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()) {
// , ,
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
*/
public class Result<T> {
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 <T> Result<T> fail(Integer code,T data) {
Result<T> ret = new Result<T>();
ret.setCode(code);
ret.setData(data);
return ret;
}
public static <T> Result<T> failMessage(Integer code,String msg) {
Result<T> ret = new Result<T>();
ret.setCode(code);
ret.setMessage(msg);
return ret;
}
public static <T> Result<T> successMessage(Integer code,String msg) {
Result<T> ret = new Result<T>();
ret.setCode(code);
ret.setMessage(msg);
return ret;
}
public static <T> Result<T> success(Integer code,T data) {
Result<T> ret = new Result<T>();
ret.setCode(code);
ret.setData(data);
return ret;
}
}
2.전단(1)플러그 인 사용
웹 업로드,다운로드 https://github.com/fex-team/webuploader/releases
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="css/webuploader.css" rel="external nofollow" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="dist/webuploader.min.js"></script>
</head>
<body>
<div id="uploader">
<div class="btns">
<div id="picker"> </div>
<button id="startBtn" class="btn btn-default"> </button>
</div>
</div>
</body>
<script type="text/javascript">
var GUID = WebUploader.Base.guid();// GUID
var uploader = WebUploader.create({
// swf
swf: 'dist/Uploader.swf',
// 。
server: 'http://localhost:8080/api/upload/part',
formData:{
guid : GUID
},
pick: '#picker',
chunked : true, //
chunkSize : 1 * 1024 * 1024, // 1M,
chunkRetry : false,// ,
threads : 1,// 。 。
resize: false
});
$("#startBtn").click(function () {
uploader.upload();
});
// 。
uploader.on( "uploadSuccess", function( file ) {
$.post('http://localhost:8080/api/upload/merge', { guid: GUID, fileName: file.name}, function (data) {
if(data.code == 200){
alert(' !');
}
});
});
</script>
</html>
(2)플러그 인 사용 안 함
직접 HTML 5 의 File API 로
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="jquery-1.10.1.min.js" type="text/javascript">
</script>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
<div id="uploader">
<div class="btns">
<input id="file" name="file" type="file"/>
<br>
<br>
<button id="startBtn">
</button>
</br>
</br>
</div>
<div id="output">
</div>
</div>
</body>
<script type="text/javascript">
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); //
for(var i = 0;i < shardCount;++i){
//
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){
// ,FormData 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); //
form.append("chunk", chunk); //
//Ajax
$.ajax({
url: "http://localhost:8080/api/upload/part",
type: "POST",
data: form,
async: true, //
processData: false, // , jquery form
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
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();
});
</script>
</html>
3.최적화
springboot 의 기본 설정 은 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
설명:설정 한 수 치 는 전단 에서 전해 오 는 것 과 같 지만,잘못 보고 하기 쉽 지 않다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.