"오늘의 문제를, 내일의 기록으로 남깁니다."

막연한 이론보다, 구체적인 코드가 필요할 때. 직접 겪고 해결한 문제들을 기록합니다. 실무에서 부딪히는 진짜 이슈와, 내가 이해한 방식 그대로 정리한 가이드입니다.

웹개발/Spring

Spring Boot에서 Multipart 파일 업로드 설정과 실전 예제 (JSP & REST 방식 모두)

자바를잡아 2025. 8. 12. 07:30
반응형

Spring Boot에서 Multipart 파일 업로드 설정과 실전 예제 (JSP & REST 방식 모두)

웹 애플리케이션에서 이미지, 문서 등의 파일 업로드 기능은 매우 흔하게 사용됩니다.
Spring Boot는 Multipart 파일 업로드를 기본적으로 지원하지만, 실무에서는 설정 누락이나 경로 오류, 파일 제한 설정 등으로 인해 자주 문제가 발생합니다.

이번 글에서는 Spring Boot에서 Multipart 업로드 설정 방법REST API 기반 파일 업로드 처리 방식, JSP 폼 전송 방식까지 단계별로 정리합니다.

1. application.yml 설정


spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 20MB
      enabled: true

기본 설정만으로도 MultipartFile은 사용 가능하지만, 용량이 큰 파일을 다루거나 multipart 기능이 비활성화된 경우 위 설정을 통해 명시해주는 것이 안전합니다.

2. 업로드 컨트롤러 (REST 방식)


@RestController
@RequestMapping("/api/files")
public class FileUploadController {

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("파일이 비어 있습니다.");
        }

        String uploadDir = "uploads/";
        String filename = UUID.randomUUID() + "_" + file.getOriginalFilename();

        Path path = Paths.get(uploadDir + filename);
        Files.createDirectories(path.getParent());
        Files.write(path, file.getBytes());

        return ResponseEntity.ok("업로드 성공: " + filename);
    }
}

- 파일을 업로드하면 로컬 uploads/ 디렉토리에 저장됩니다.
- 실제로는 S3, NAS, 클라우드 저장소와 연동되는 구조로 확장 가능합니다.

3. 업로드 테스트 HTML 폼

간단한 테스트용 HTML 클라이언트입니다.


<form action="/api/files/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <button type="submit">업로드</button>
</form>

4. JSP 방식으로 업로드 처리

JSP를 사용하는 프로젝트라면 CommonsMultipartResolver를 등록하거나 Spring Boot 내장 설정을 그대로 활용하면 됩니다.


@Controller
public class LegacyUploadController {

    @PostMapping("/legacy-upload")
    public String legacyUpload(@RequestParam("file") MultipartFile file, Model model) throws IOException {
        String filename = file.getOriginalFilename();
        model.addAttribute("msg", filename + " 업로드 성공");
        return "result.jsp";
    }
}

5. 오류 발생 시 점검 포인트

  • HTTP 400 Bad Request: form의 enctype="multipart/form-data"가 빠졌을 때
  • MultipartFile이 null: @RequestParam("file") 이름이 실제 input name과 다를 때
  • 403/405 에러: 보안 설정(CSRF, CORS 등) 또는 POST 메서드 허용 여부 확인
  • 파일이 저장되지 않음: 경로가 잘못됐거나, Files.createDirectories() 호출 누락

6. 보안적으로 꼭 고려해야 할 사항

  • 업로드 파일 확장자 제한 (이미지, 문서 등)
  • 디렉토리 트래버설 공격 방지 (e.g. ../../webapp)
  • 서버 저장소 용량 체크 또는 제한
  • 업로드 파일명 난수화 또는 UUID로 처리

7. 기타 팁

  • 파일 용량 제한은 클라이언트(front) + 서버 모두에서 체크
  • 업로드 처리 로직은 Service 레이어로 분리하는 것이 실무에선 깔끔함
  • 여러 파일을 동시에 받을 경우: List<MultipartFile>로 처리 가능

// 다중 파일 업로드
@PostMapping("/multi-upload")
public ResponseEntity<?> uploadFiles(@RequestParam("files") List<MultipartFile> files) {
    for (MultipartFile file : files) {
        // 반복 처리
    }
    return ResponseEntity.ok("완료");
}

정리

  • Spring Boot는 MultipartFile 기반 파일 업로드를 기본적으로 지원함
  • application.yml 설정으로 용량 제한을 명시할 수 있음
  • REST API 방식과 JSP 방식 모두 대응 가능
  • 보안 및 파일명 관리도 꼭 신경 써야 함

맺음말

파일 업로드는 간단해 보여도 의외로 많은 문제가 발생하는 기능입니다.
이번 글에서 다룬 방식은 Spring Boot의 기본 구조에 맞춰 가장 보편적이고 실무에서 많이 쓰이는 예제입니다.
직접 테스트하고, 파일 업로드 기능을 서비스에 맞게 확장해보시기 바랍니다.

반응형