공부하기/Spring
[SpringBoot] 파일 업로드를 위한 MultipartFile의 처리/동작 방식
다섯자두
2025. 4. 9. 15:20
Spring에서는 ``MultipartFile`` 인터페이스를 통해 파일 업로드 기능을 간편하게 구현할 수 있다.
1. Multipart Upload란?
이미지, 영상, 문서 등의 바이너리 데이터를 업로드하기 위한 HTTP 요청 방식이다.
요청의 ``Content-Type``은 ``multipart/form-data``로 지정되며,
데이터는 요청 본문(Body)에 다음과 같이 구성된다.
- Header : Content-Type, 필드 이름 등 메타데이터
- Body: 실제 데이터 (파일, 폼 필드 값 등)
Multipart Upload 요청 예시
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="username"
Alex_Obregon
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain
This is the content of the file.
------WebKitFormBoundary--
☑️ Spring에서의 Multipart 처리 방식
Spring Boot에서는 ``MultipartResolver``를 통해 multipart/form-data 요청을 자동으로 감지하고 처리한다.
- multipart/form-data 타입으로 들어오는 HTTP Request들을 감지한다.
- 요청 본문을 파싱하고 각 파트를 분리한다.
- 파일은 ``MultipartFile`` 객체로, 텍스트 필드는 ``@RequestParam`` 등을 통해 주입한다.
예시
예를 들어 다음과 같은 요청이 들어오면,
POST /upload HTTP/1.1
Host: yourserver.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain
This is the content of the file.
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="description"
This is a test description.
------WebKitFormBoundary7MA4YWxkTrZu0gW--
아래 컨트롤러에서 각 파트들을 파싱해서 받아올 수 있게 한다.
@PostMapping("/upload")
public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file,
@RequestParam("description") String description) {
String fileName = file.getOriginalFilename();
long fileSize = file.getSize();
return ResponseEntity.ok("Received file: " + fileName + " (" + fileSize + " bytes) with description: " + description);
}
2. 업로드된 파일의 임시 저장 처리
파일 업로드 시 서버는 해당 파일 데이터를 임시로 저장해야 한다.
이 장소는 설정에 따라 메모리 혹은 디스크 중 하나를 사용한다.
Memory (RAM)
- 말 그대로 RAM에 임시적으로 저장한다.
- 파일 크기가 작을 때에는 빠르고 효율적이다.
- 너무 많은 파일이나 큰 파일이 한꺼번에 들어온다면 작고 소중한 메모리가 터질 수 있다 .. 🥶
Disk-backed Buffers
- 디스크에 임시 저장해놓는 방식이다. (하드디스크, SSD)
- 처리 속도는 메모리에 비해 느리지만 안정적이다.
☑️ Spring의 파일 임시 저장소
Spring은 기본적으로 서블릿 컨테이너(Tomcat)가 실행 중인 서버의 디스크 공간을 임시 저장소로 사용한다.
``spring.servlet.multipart.file-size-threshold`` 설정을 통해 파일이 특정 크기 미만일 경우 메모리에, 이상일 경우 디스크에 저장되도록 할 수 있다. (default는 0B로, 모두 디스크에 임시 저장된다.)
- 이 디스크는 서버가 돌아가고 있는 운영체제의 파일 시스템 내 특정 경로를 의미한다.
- 요청이 들어오면 디스크에 임시 파일을 만들어 저장하고, 요청이 정상 종료된다면 자동으로 삭제한다.
- 이 때, 배포 중단, 서버 장애 발생 시 삭제 처리가 되지 않는 경우가 발생할 수 있다.
- 따라서 임시 경로를 명시하고 주기적으로 정리하는 것이 바람직하다.
☑️ MultipartFile의 동작 원리
Spring은 디스크에 저장된 파일을 ``MultipartFile`` 객체에 매핑한다.
- 전체 파일 데이터를 Heap 메모리에 올리지 않는다.
- 파일 이름, 크기, 타입 등 메타데이터만 저장한다.
- 실제 파일 데이터는 InputStream 등을 통해 접근한다.
마무리
MultipartFile에 대해 처리 방식, 동작 원리까지 정리해봤다.
막연했던 개념이 정리되니까 속이 시원하다.