본문 바로가기
스프링 부트3

스프링 부트 3에서 파일 업로드 구현

by 굿센스굿 2024. 12. 4.
반응형

 

1. 개요

파일 업로드는 대부분의 웹 애플리케이션에서 필수적인 기능 중 하나입니다. 스프링 부트 3에서는 파일 업로드를 쉽게 구현할 수 있는 다양한 기능을 제공합니다. 이 글에서는 스프링 부트 3 기반으로 파일 업로드를 처리하는 방법을 설명하고, 구현 예제와 함께 주요 고려 사항을 다룹니다.


2. 스프링 부트 3에서 파일 업로드 처리

2.1 파일 업로드 기본 개념

파일 업로드란 클라이언트가 로컬 파일을 서버로 전송하는 과정입니다. 스프링 부트에서는 MultipartFile 인터페이스를 사용하여 파일을 쉽게 처리할 수 있습니다. 이 인터페이스는 파일 이름, 크기, MIME 타입 등의 메타데이터와 파일 데이터를 관리합니다.

2.2 스프링 부트 3의 주요 파일 업로드 지원

  • Spring MVC의 멀티파트 지원: MultipartFile을 통해 파일 데이터를 다룰 수 있습니다.
  • Spring Boot Starter: 스프링 부트는 기본적으로 spring-boot-starter-web 의존성에 파일 업로드 기능을 포함합니다.
  • 설정 간소화: 기본적으로 업로드 파일 크기와 저장 위치를 간단히 설정할 수 있습니다.

3. 파일 업로드 구현

3.1 파일 업로드 설정

스프링 부트에서 파일 업로드 설정은 application.properties 또는 application.yml 파일을 사용하여 지정할 수 있습니다.

설정 예제

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=15MB
  • max-file-size: 업로드 가능한 단일 파일의 최대 크기
  • max-request-size: 요청 전체의 최대 크기

3.2 파일 업로드 REST 컨트롤러

스프링 부트 3에서 파일 업로드를 처리하는 기본 컨트롤러 구현 예제는 다음과 같습니다.

예제 1: 단일 파일 업로드

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

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

        String fileName = file.getOriginalFilename();
        Path path = Paths.get("uploads/" + fileName);

        try {
            Files.createDirectories(path.getParent());
            Files.write(path, file.getBytes());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("파일 저장 중 오류 발생");
        }

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

3.3 다중 파일 업로드

다중 파일 업로드는 List<MultipartFile>을 사용하여 처리할 수 있습니다.

예제 2: 다중 파일 업로드

@PostMapping("/upload-multiple")
public ResponseEntity<String> uploadMultipleFiles(@RequestParam("files") List<MultipartFile> files) {
    if (files.isEmpty()) {
        return ResponseEntity.badRequest().body("업로드된 파일이 없습니다.");
    }

    files.forEach(file -> {
        String fileName = file.getOriginalFilename();
        Path path = Paths.get("uploads/" + fileName);

        try {
            Files.createDirectories(path.getParent());
            Files.write(path, file.getBytes());
        } catch (IOException e) {
            throw new RuntimeException("파일 저장 중 오류 발생: " + fileName, e);
        }
    });

    return ResponseEntity.ok("모든 파일 업로드 성공");
}

3.4 업로드된 파일 확인 및 다운로드

업로드된 파일을 확인하거나 다운로드할 수 있는 API도 자주 필요합니다.

예제 3: 파일 다운로드

@GetMapping("/download/{fileName}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
    Path path = Paths.get("uploads/" + fileName);
    Resource resource;

    try {
        resource = new UrlResource(path.toUri());
        if (!resource.exists() || !resource.isReadable()) {
            throw new RuntimeException("파일을 읽을 수 없습니다: " + fileName);
        }
    } catch (MalformedURLException e) {
        throw new RuntimeException("URL이 잘못되었습니다.", e);
    }

    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
            .body(resource);
}

4. 파일 업로드 시 고려사항

  1. 보안
    • 업로드 파일 이름에서 경로 탐색(Path Traversal) 공격을 방지해야 합니다.
    • 허용된 파일 형식만 업로드 가능하도록 MIME 타입을 검사하세요.
  2. 파일 크기 제한
    • 설정 파일에서 최대 파일 크기를 명확히 지정하고, 큰 파일은 거부 처리합니다.
  3. 성능
    • 파일 저장소를 로컬 디스크 대신 클라우드 스토리지(AWS S3, Azure Blob 등)로 확장하는 것을 고려하세요.

5. 결론

스프링 부트 3는 파일 업로드를 구현하기 위한 간단하고 강력한 도구를 제공합니다. 위의 예제와 설정을 참고하여 단일 또는 다중 파일 업로드 기능을 효과적으로 구현할 수 있습니다. 보안, 성능, 확장성까지 고려한 안정적인 파일 업로드 시스템을 구축해보세요!

반응형