헤르메스 LIFE

[Spring Boot] 개발환경 구축 - File Upload 본문

Spring Boot Framework

[Spring Boot] 개발환경 구축 - File Upload

헤르메스의날개 2023. 2. 4. 01:07
728x90

AppSpringBoot.zip
0.14MB

개발환경

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와 같이 눈으로 보기에도 굉장히 지저분한 경로가 생성될 수 있어요.

요청 처리 후에는 파일이 삭제되도록 되어있지만, 운영하다보면 결국 남아있는 것은 어떤 이유로든 남게 되있어요.

그럴 경우에는 삭제 처리를 별도로 해야하기 때문에 작업과 관리가 용이하도록 경로를 직접 설정해주는 것이 좋아요.

홍아지님의 글을 참고 하였습니다.

https://gofnrk.tistory.com/36

 

Spring Boot 파일 업로드 MultipartFile

Spring의 MultipartFile 인터페이스를 이용하여 파일 업로드하는 방법에 대해서 알아볼게요. 파일을 리스트로 여러 개 업로드하면 컨트롤러에서 받을 수 있도록 할거에요. 간단하게 말해서 다중 업로

gofnrk.tistory.com

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

 

[Spring Boot] Multi FileUpload

개발환경 1. STS 버전 : 4.13.1 2. JDK 버전 : OpenJDK 11.0.14_9_x64 3. Tomcat 버전 : 9.0.56 4. Maven 버전 : 3.8.4 5. Spring 버전 : Spring Boot 2.6.3 6. Database : Docker 에 DB 설치 - primary - PostgreSQL 13.3 8. lombok 프로젝트 목표 1.

hermeslog.tistory.com

https://hermeslog.tistory.com/650

 

[Spring] 개발환경 구축 - File Upload

Spring 개발환경을 갑자기 구축하려고 하다보니, 막막합니다. 하나 하나 구축해 보겠습니다 개발환경 Spring 4.3.30.RELEASE MAVEN 3.8.4 Logback 1.2.9 commons-fileupload 1.4 commons-io 2.6 pom.xml 4.0.0 SimpleSpring4 SimpleSpr

hermeslog.tistory.com

https://gofnrk.tistory.com/36

 

Spring Boot 파일 업로드 MultipartFile

Spring의 MultipartFile 인터페이스를 이용하여 파일 업로드하는 방법에 대해서 알아볼게요. 파일을 리스트로 여러 개 업로드하면 컨트롤러에서 받을 수 있도록 할거에요. 간단하게 말해서 다중 업로

gofnrk.tistory.com

 

728x90