Backend Development/SPRING

MultipartFile

foreverWon 2025. 7. 30. 14:20
목차

    기능

    • MultipartFile은 Spring에서 HTTP multipart 요청을 통해 업로드된 파일을 서버에서 처리하기 위한 인터페이스
    • 파일을 쉽게 받고, 검증하고, 저장하는 작업을 추상화

    내부 구조 및 주요 메서드

    • getOriginalFilename() : 클라이언트가 전송한 파일 원본 이름 반환
    • getContentType() : 파일의 MIME 타입 (예: image/png, text/csv) 반환
    • getSize() : 파일 크기(byte) 반환
    • getBytes() : 파일 내용을 byte 배열로 반환
    • getInputStream() : 파일 내용을 InputStream으로 반환
    • transferTo(File dest) : 서버 디스크에 파일 저장 (직접 경로 지정)

    동작 방식

    • 클라이언트는 HTTP 요청 시 Content-Type: multipart/form-data 헤더를 포함하여 파일과 일반 폼 데이터를 함께 전송
    • Spring MVC는 이를 자동으로 파싱해 MultipartFile 객체로 컨트롤러에 전달
    • 개발자는 @RequestParam("file") MultipartFile file 형태로 쉽게 파일을 받을 수 있음

    주의할 점

    • 파일 크기 제한 : 서버 부하 방지를 위해 application 설정에서 spring.servlet.multipart.max-file-size와 max-request-size 설정 필수
    • 파일 타입 검증 : 허용된 확장자 및 MIME 타입만 처리하도록 로직 구현 권장
    • 보안 위험 방지 : 파일명에 대한 클린징, 악성코드 여부 검증 필요할 수 있음
    • 파일 저장 경로 관리 : 서버 내 고정 경로나 클라우드 저장소 연동 고민
    • 에러 처리 : 업로드 실패, 파일 없음, 권한 문제 등에 대한 예외 핸들링

    요약

    항목  내용
    목적 HTTP multipart/form-data 방식의 파일 업로드 지원
    주요 메서드 getOriginalFilename, getContentType, getSize, transferTo 등
    사용 환경 Spring MVC Controller 내 파일 수신 및 처리
    장점 Spring의 자동 파싱 및 객체화로 파일 처리 편리
    주의사항 파일 크기/타입 검증, 저장 경로 관리, 보안 위험 대비 필요

    코드

    @PostMapping("/api/files/profile")
    public ResponseEntity<?> uploadProfile(@RequestParam("file") MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("파일이 없습니다.");
        }
        
        // 확장자 검사 예시
        String filename = file.getOriginalFilename();
        if (filename != null && !(filename.endsWith(".jpg") || filename.endsWith(".png"))) {
            return ResponseEntity.badRequest().body("이미지 파일만 업로드 가능합니다.");
        }
        
        // 저장 경로 지정 및 저장
        String storedFileName = UUID.randomUUID() + "_" + filename;
        Path savePath = Paths.get("uploads/profile/", storedFileName);
        file.transferTo(savePath);
        
        return ResponseEntity.ok("업로드 성공");
    }
    728x90