Handler Method : Multipart

2024. 10. 9. 16:29Spring Framework/Web on Servlet Stack

Spring에서 Multipart 요청 처리 완벽 정리 🚀

Multipart 요청은 파일과 함께 다양한 형식의 데이터를 서버로 전송할 수 있는 요청입니다.
Spring에서는 MultipartResolver를 활성화하고, MultipartFile 또는 Part 객체를 사용하여 파일 업로드 및 JSON 데이터를 동시에 처리할 수 있습니다.

📌 1️⃣ Multipart 요청 개념

MultipartFile파일 업로드를 처리하는 Spring 인터페이스
@RequestParam폼 데이터(multipart/form-data)에서 파일을 처리
@RequestPartJSON + 파일을 함께 전송할 때 사용
MultipartResolverSpring이 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 요청을 처리하는 다양한 방법을 숙지하면, 파일 업로드 기능을 더욱 효과적으로 구현할 수 있습니다!

출처 : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/multipart-forms.html

 

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

 

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

Handler Method : HttpEntity  (0) 2024.10.09
Handler Mapping : @RequestBody  (0) 2024.10.09
Handler Method : Flash Attributes  (0) 2024.10.09
Handler Method : Redirect Attributes  (0) 2024.10.09
HttpServletRequest  (0) 2024.10.09