멀티파트 업로드: 제한/보안/임시저장 설계
파일 업로드는 용량 제한, 확장자/시그니처 검사, 임시 저장소 설계가 핵심입니다.
안전한 파이프라인을 만들지 않으면 OOM이나 악성 파일 유입 위험이 있습니다.
설정
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 25MB
location: /tmp/upload # 임시 저장 디렉터리
컨트롤러
@PostMapping(value="/api/upload", consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public UploadResponse upload(@RequestPart("file") MultipartFile file) throws IOException {
guard(file);
Path tmp = Files.createTempFile("up-", ".bin");
file.transferTo(tmp);
// TODO: 시그니처 검사/바이러스 스캔/이미지 처리
// ex) Tika로 MIME 판별, Thumbnailator로 썸네일 등
Path saved = storage.save(tmp, file.getOriginalFilename());
Files.deleteIfExists(tmp);
return new UploadResponse(saved.toString());
}
검증(간단 예)
void guard(MultipartFile file) {
if (file.isEmpty()) throw new IllegalArgumentException("빈 파일");
if (file.getSize() > 20 * 1024 * 1024) throw new IllegalArgumentException("용량 초과");
String name = Optional.ofNullable(file.getOriginalFilename()).orElse("");
if (!name.matches("(?i).+\\.(png|jpg|jpeg|pdf)$")) throw new IllegalArgumentException("허용 확장자 아님");
}
운영 팁
- 임시 디스크는 별도 파티션/용량 모니터링
- 신뢰할 수 없는 입력은 Content-Type 대신 매직넘버/시그니처로 판단
- 대용량은 클라이언트 직업로드(S3 pre-signed URL) + 서버는 메타만 처리
FAQ
Q1. 저장 전에 이미지 크기 알아내기?
A. ImageIO로 스트림에서 메타를 읽어 검증한 뒤 저장.
Q2. 동시 업로드가 많으면?
A. 업로드 전용 스레드풀과 큐 용량을 제한하고, 백프레셔 정책을 명확히 하세요.
👉 1편: Bean Validation(@Valid)로 입력 검증 표준 만들기
👉 2편: @ControllerAdvice 글로벌 예외 응답(에러코드 규격)
👉 3편: application-{profile}.yml 전략 + 비밀키 분리
👉 4편: Spring Boot Actuator: /health 커스터마이징
👉 5편: @Scheduled 크론 12패턴 + 중복실행 방지
'Java & Spring' 카테고리의 다른 글
| Pageable 응답 DTO 규격(정렬·페이지 표준화) (0) | 2025.09.30 |
|---|---|
| Spring Cache로 API 3배 빠르게(@Cacheable/무효화) (0) | 2025.09.30 |
| @Scheduled 크론 12패턴 + 중복실행 방지 (0) | 2025.09.30 |
| Spring Boot Actuator: /health 커스터마이징 (0) | 2025.09.30 |
| application-{profile}.yml 전략 + 비밀키 분리 (0) | 2025.09.30 |