Handler Method : Multipart
Spring에서 Multipart 요청 처리 완벽 정리 🚀
Multipart 요청은 파일과 함께 다양한 형식의 데이터를 서버로 전송할 수 있는 요청입니다.
Spring에서는 MultipartResolver
를 활성화하고, MultipartFile
또는 Part
객체를 사용하여 파일 업로드 및 JSON 데이터를 동시에 처리할 수 있습니다.
📌 1️⃣ Multipart 요청 개념
✅ MultipartFile
→ 파일 업로드를 처리하는 Spring 인터페이스
✅ @RequestParam
→ 폼 데이터(multipart/form-data
)에서 파일을 처리
✅ @RequestPart
→ JSON + 파일을 함께 전송할 때 사용
✅ MultipartResolver
→ Spring이 Multipart 요청을 처리할 수 있도록 활성화하는 설정
📌 2️⃣ Spring에서 파일 업로드 처리 (MultipartFile
)
✅ 단일 파일 업로드 (@RequestParam
)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class FileUploadController {
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// 파일 저장 로직
return "redirect:/uploadSuccess";
} catch (Exception e) {
e.printStackTrace();
}
}
return "redirect:/uploadFailure";
}
}
✔ @RequestParam("file") MultipartFile file
✔ file.getBytes()
를 사용하여 파일 데이터를 바이트 배열로 읽음
✅ 여러 파일 업로드 (List<MultipartFile>
)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@Controller
public class MultiFileUploadController {
@PostMapping("/multiUpload")
public String handleMultiUpload(@RequestParam("files") List<MultipartFile> files) {
for (MultipartFile file : files) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// 각각의 파일 저장 처리
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "redirect:/uploadSuccess";
}
}
✔ 여러 파일을 List<MultipartFile>
로 받아서 처리
✔ file.getBytes()
를 사용하여 각각의 파일을 저장
📌 3️⃣ JSON과 파일을 함께 업로드 (@RequestPart
)
✅ 파일 + JSON 데이터 함께 처리
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class JsonFileUploadController {
@PostMapping("/upload")
public String handleUpload(@RequestPart("meta-data") MetaData metadata,
@RequestPart("file-data") MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// 파일 및 JSON 데이터 처리
return "redirect:/uploadSuccess";
} catch (Exception e) {
e.printStackTrace();
}
}
return "redirect:/uploadFailure";
}
}
✔ @RequestPart("meta-data")
→ JSON을 객체로 변환
✔ @RequestPart("file-data")
→ 파일을 MultipartFile
로 변환
✅ HTTP 요청 예시 (multipart/mixed
)
POST /upload
Content-Type: multipart/mixed; boundary=edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
{
"name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.txt"
Content-Type: text/plain
... File Data ...
✔ meta-data: JSON 형식의 데이터 (@RequestPart("meta-data")
)
✔ file-data: 파일 (@RequestPart("file-data")
)
📌 4️⃣ JSON 데이터 유효성 검사 (@Valid
사용)
✅ 유효성 검사 (@Valid + Errors
)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import jakarta.validation.Valid;
import org.springframework.validation.Errors;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class ValidatedUploadController {
@PostMapping("/upload")
public String handleUpload(@Valid @RequestPart("meta-data") MetaData metadata,
Errors errors,
@RequestPart("file-data") MultipartFile file) {
if (errors.hasErrors()) {
return "uploadForm"; // 유효성 검사 실패 시 다시 폼으로 이동
}
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// 파일 저장 로직
return "redirect:/uploadSuccess";
} catch (Exception e) {
e.printStackTrace();
}
}
return "redirect:/uploadFailure";
}
}
✔ @Valid
를 사용하여 JSON 데이터 검증
✔ Errors
객체로 유효성 검사 결과 확인
✔ 파일이 비어 있는지 확인 후 저장 로직 실행
📌 5️⃣ MultipartResolver
설정
Spring이 Multipart 요청을 처리할 수 있도록 MultipartResolver
를 활성화해야 합니다.
✅ Spring Boot에서 자동 설정 (StandardServletMultipartResolver
)
Spring Boot에서는 자동으로 MultipartResolver
가 설정되므로 추가 설정이 필요하지 않습니다.
✅ Spring MVC에서 수동 설정 (CommonsMultipartResolver
)
Spring MVC에서는 CommonsMultipartResolver
를 Bean으로 등록해야 합니다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@Configuration
public class MultipartConfig {
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10 * 1024 * 1024); // 최대 업로드 크기 설정 (10MB)
return resolver;
}
}
✔ CommonsMultipartResolver
를 사용하여 최대 업로드 크기 설정 가능
📌 6️⃣ Summary
✅ 파일 업로드 (MultipartFile
)
@RequestParam("file") MultipartFile file
→ 단일 파일 처리List<MultipartFile>
→ 여러 개의 파일 처리
✅ JSON + 파일 함께 업로드 (@RequestPart
)
@RequestPart("meta-data")
→ JSON을 객체로 변환@RequestPart("file-data")
→ 파일을MultipartFile
로 변환
✅ 유효성 검사 (@Valid + Errors
)
@Valid
를 사용하여 JSON 데이터 검증 가능Errors
객체로 유효성 검사 결과 확인
✅ MultipartResolver 설정
- Spring Boot → 자동 설정됨
- Spring MVC → CommonsMultipartResolver 수동 등록 필요
🚀 Spring에서 Multipart 요청을 처리하는 다양한 방법을 숙지하면, 파일 업로드 기능을 더욱 효과적으로 구현할 수 있습니다!
Multipart :: Spring Framework
When the @RequestParam annotation is declared as a Map or MultiValueMap , without a parameter name specified in the annotation, then the map is populated with the multipart files for each given parameter name. You can also use multipart content as part of
docs.spring.io