일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Thymeleaf
- Docker
- PostgreSQL
- Python
- IntelliJ
- Spring Boot
- maven
- 오픈소스
- 문서
- oracle
- JavaScript
- AJAX
- Exception
- myBatis
- STS
- 설정
- MSSQL
- Core Java
- MySQL
- spring
- Source
- git
- JDBC
- Eclipse
- ubuntu
- error
- Open Source
- Tomcat
- jpa
- SpringBoot
- Today
- Total
헤르메스 LIFE
[Spring Boot] 개발환경 구축 - File Upload 본문
개발환경
1. STS 버전 : 4.13.1
2. JDK 버전 : OpenJDK 11.0.14_9_x64
3. Tomcat 버전 : 9.0.71
4. Maven 버전 : 3.8.4
5. Spring 버전 : Spring Boot 2.7.8
6. Thymeleaf 3.0.15
spring.servlet.multipart.enabled: 멀티파트 업로드 지원여부 (default: true)
spring.servlet.multipart.file-size-threshold: 파일이 메모리에 기록되는 임계값 (default: 0B)
spring.servlet.multipart.location: 업로드된 파일의 임시 저장 공간
spring.servlet.multipart.max-file-size: 파일의 최대 사이즈 (default: 1MB)
spring.servlet.multipart.max-request-size: 요청의 최대 사이즈 (default: 10MB)
application-dev.yml
# Logging
logging:
pattern:
console: "[DEV] %-5level %d{yy-MM-dd HH:mm:SSS}[%thread] [%logger.%method:%line] - %msg%n"
file: "[DEV] %-5level %d{yy-MM-dd HH:mm:SSS}[%thread] %logger[%method:%line] - %msg%n"
file:
name: C:/greenhorn/logs/logback-dev#2.log
logback:
rollingpolicy:
max-file-size: 1MB #default 10M
max-history: 31 #default 7
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
# Server port
server:
port: 9091
servlet:
context-path: /
encoding:
enabled: true
charset: UTF-8
force: true
session:
timeout: 120 # 기본단위 : 초
tomcat:
uri-encoding: UTF-8 # Spring Default : UTF-8
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
thymeleaf:
cache: false
# FATAL and ERROR – Red
# WARN – Yellow
# INFO, DEBUG and TRACE – Green
output:
ansi:
enabled: DETECT
# 파일업로드 경로
comm:
uploadPath: C:/temp/upload/
파일의 크기가 fize-size-threshold 값 이하라면 임시파일을 생성하지 않고 메모리에서 즉시 파일을 읽어서 생성할 수 있어요. 속도는 더 빠르겠지만, 쓰레드가 작업을 수행하는 동안 부담이 되는 부분이기 때문에 충분한 검토가 필요한 설정이에요.
파일의 크기가 fize-size-threshold 값을 초과한다면 파일은 spring.servlet.multipart.location 경로에 저장되어 해당 파일을 읽어서 작업을 하도록 되어있어요.
참고로 location을 설정하지 않으면 System.getProperty("java.io.tmpdir"); 경로에 저장이 되요.
아래 이미지의 path와 같이 눈으로 보기에도 굉장히 지저분한 경로가 생성될 수 있어요.
요청 처리 후에는 파일이 삭제되도록 되어있지만, 운영하다보면 결국 남아있는 것은 어떤 이유로든 남게 되있어요.
그럴 경우에는 삭제 처리를 별도로 해야하기 때문에 작업과 관리가 용이하도록 경로를 직접 설정해주는 것이 좋아요.
홍아지님의 글을 참고 하였습니다.
FileUploadController.java
package simple.spring.file;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import simple.spring.file.repository.FileSaveRepository;
import simple.spring.file.vo.FileVO;
@Controller
public class FileUploadController {
private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);
@Autowired
private MessageSourceAccessor messageSourceAccessor;
// application-xxx.yml에서 값을 가져옵니다.
@Value("${comm.uploadPath}")
private String UPLOAD_LOCATION;
@Autowired
private FileSaveRepository fileSaveRepository;
@GetMapping("/singleUpload")
public String getSingleUploadPage(ModelMap model) {
return "upload/singleFileUploader";
}
@GetMapping("/multiUpload")
public String getMultiUploadPage(ModelMap model) {
return "upload/multiFileUploader";
}
@PostMapping("/fileUpload")
public String fileUpload(@RequestParam("files") MultipartFile[] files, ModelMap model,
RedirectAttributes redirectAttributes) throws IOException, Exception {
logger.debug("파일개수 : {}", files.length);
List<String> fileList = new ArrayList<>();
FileVO fileVO = null;
if (files.length > 0) {
for (int i = 0; i < files.length; i++) {
fileVO = new FileVO();
String fileName = files[i].getOriginalFilename();
String fileExt = fileName.substring(fileName.lastIndexOf("."));
logger.debug("UPLOAD_LOCATION : {}", UPLOAD_LOCATION);
logger.debug("파일 이름 : {}", fileName);
logger.debug("파일 확장자 : {}", fileExt);
logger.debug("파일 크기 : {}", files[i].getSize());
String uuidFile = UUID.randomUUID().toString().replaceAll("-", "") + fileExt;
logger.debug("UUID 파일명 : {}", uuidFile);
String uploadFile = UPLOAD_LOCATION + uuidFile;
logger.debug("업로드 파일 : {}", uploadFile);
try {
if (files[i].isEmpty()) {
throw new IOException(messageSourceAccessor.getMessage("common.file.empty")); // 빈 파일입니다.
}
File Folder = new File(uploadFile);
if ( !Folder.exists() ) {
try {
Folder.mkdirs();
logger.debug("폴더가 생성되었습니다.");
} catch (Exception e) {
e.getStackTrace();
}
}
Path destinationFile = Paths.get(uploadFile);
try (InputStream inputStream = files[i].getInputStream()) {
Files.copy(inputStream, destinationFile, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException("file Save Error");
}
fileList.add(fileName);
fileVO.setOrgnFileName(fileName); // fileName
fileVO.setTempFileName(uploadFile); // 경로 + 변경된 파일명
fileSaveRepository.save(fileVO);
}
}
model.addAttribute("fileNames", fileList);
redirectAttributes.addFlashAttribute("message", "You successfully uploaded !");
return "upload/success";
}
}
https://hermeslog.tistory.com/577
https://hermeslog.tistory.com/650
'Spring Boot Framework' 카테고리의 다른 글
[Spring Boot] Application.yml 설정 - Hibernate – SQL Dialects (0) | 2023.02.26 |
---|---|
[Spring Boot] Spring Boot에서 properties 값 주입받기 (0) | 2023.02.04 |
[Spring Boot] 개발환경 구축 - Messages (0) | 2023.02.01 |
[Spring Boot] Spring Boot 배포전략 (0) | 2023.01.31 |
[Spring Boot] 개발환경 구축 - Logback (0) | 2023.01.29 |