Handler Method : Multipart

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


**Multipart 요청**은 파일과 함께 다양한 형식의 데이터를 서버로 전송할 수 있는 **multipart/form-data** 형식의 요청입니다. 스프링에서는 `MultipartResolver`를 활성화한 후 이러한 요청을 처리할 수 있으며, `MultipartFile` 또는 `Part` 객체를 통해 파일을 받아 처리할 수 있습니다. 또한, JSON과 같은 다른 형식의 데이터를 함께 전송할 때는 `@RequestPart`를 사용하여 데이터를 처리할 수 있습니다.

기본 개념

  • MultipartFile: 스프링에서 파일 업로드를 처리할 때 주로 사용하는 인터페이스로, 업로드된 파일의 이름, 크기, 바이트 데이터를 처리할 수 있습니다.
  • @RequestParam: 폼 데이터를 처리할 때 사용되며, 파일 업로드 시 MultipartFile을 통해 데이터를 받아 처리합니다.
  • @RequestPart: JSON과 같은 데이터와 파일을 동시에 처리할 때 사용하며, JSON은 객체로 변환되고 파일은 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;

@Controller
public class FileUploadController {

    @PostMapping("/form")
    public String handleFormUpload(@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: MultipartFile 타입으로 파일을 받아 처리합니다.
  • 파일 처리: file.getBytes()로 파일의 데이터를 바이트 배열로 읽어와 저장하거나 다른 작업을 수행합니다.

여러 파일 업로드 처리

여러 파일을 동시에 업로드하려면 List<MultipartFile> 또는 Map<String, 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>: 여러 파일을 받을 때 List<MultipartFile>로 처리할 수 있습니다.
  • 각각의 파일을 처리하는 로직을 작성해, 파일을 저장하거나 다른 작업을 수행할 수 있습니다.

JSON과 파일을 함께 업로드 처리 (@RequestPart 사용)

다음 예시에서는 JSON 데이터와 파일을 동시에 전송할 때의 처리 방식을 보여줍니다. 이를 위해 @RequestPart를 사용하여 JSON은 객체로, 파일은 MultipartFile로 받습니다.

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();
                // 파일 및 메타 데이터 처리 로직
                return "redirect:/uploadSuccess";
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "redirect:/uploadFailure";
    }
}

코드 설명:

  • @RequestPart("meta-data"): JSON 데이터를 MetaData 객체로 변환하여 받아옵니다.
  • @RequestPart("file-data"): 파일을 MultipartFile로 받아 처리합니다.

HTTP 요청 예시: multipart/mixed로 JSON과 파일을 함께 전송

POST /someUrl
Content-Type: multipart/mixed; boundary=edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp

--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit

{
    "name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.properties"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit

... File Data ...

이 요청은 두 부분으로 나뉩니다:

  1. meta-data: JSON 형식의 데이터로 전송되며, @RequestPart를 통해 객체로 변환됩니다.
  2. file-data: 파일 데이터가 전송되며, 이는 MultipartFile로 처리됩니다.

유효성 검사와 JSON 데이터 처리

@RequestPart로 받은 JSON 데이터는 유효성 검사를 할 수 있습니다. @Valid 어노테이션과 Errors 또는 BindingResult를 사용하여 유효성 검사를 수행할 수 있습니다.

유효성 검사 예시

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: MetaData 객체에 대해 유효성 검사를 수행합니다.
  • Errors: 유효성 검사에서 오류가 발생하면 Errors 객체에 저장됩니다. 이 오류 정보를 바탕으로 적절한 오류 처리를 할 수 있습니다.

요약

  • MultipartFile은 파일 업로드를 처리할 때 사용하는 인터페이스입니다. 이를 사용하여 업로드된 파일을 처리하고 저장할 수 있습니다.
  • @RequestPart는 JSON 데이터와 파일을 동시에 처리할 때 사용됩니다. JSON은 객체로 변환되고, 파일은 MultipartFile로 처리됩니다.
  • 유효성 검사@ValidErrors를 사용하여 처리할 수 있으며, JSON 데이터의 유효성을 검사할 수 있습니다.
  • HTTP 요청에서는 multipart/mixed 형식을 사용하여 JSON과 파일 데이터를 함께 전송할 수 있으며, 스프링에서 이를 @RequestPart로 처리합니다.


참고 : [https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/multipart-forms.html](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/multipart-forms.html)