muiltipart/form-data : 클라이언트가 파일을 보내는 형식
HTTP 프로토콜에서 서버에 이미지와 같은 파일 (바이너리 데이터) 를 보낼 때 multipart/form-data 콘텐츠 유형을 사용한다.
multipart/form-data 형식을 통해 HTTP 요청을 보내는 경우, 요청 메시지는 여러 부분 (part) 로 구성되며, 각 부분은 파일이나 텍스트 데이터를 포함하게 된다.
예를 들면 다음과 같은 HTTP 요청 메시지가 전송된다.
- message header
POST /api/upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 12345
- message body
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.png"
Content-Type: image/png
<파일 내용>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="description"
This is an example description text.
------WebKitFormBoundary7MA4YWxkTrZu0gW--
각 파트는 header 의 boundary 에 작성한 문자열로 구분되며, body 의 각 파트들은 Content-Disposition 과 Content-Type 으로 각 파트의 정보를 기술한다.
multipart/form-data를 사용하는 이유REST API 에서 주로 사용하는
application/json과 같은 텍스트 기반은 바이너리 데이터나 ASCII 문자가 아닌 텍스트를 전송하는데 비효율적이기 때문이다.파일과 같은 바이너리 데이터를 JSON 과 같은 텍스트 기반 형식으로 전송하려면
Base64인코딩이 필요하다.Base64는 데이터 크기를 증가시키고, 인코딩과 디코딩 과정의 오버헤드를 발생시키기 때문에 대역폭과 처리 시간을 증가시키는 비효율성을 초래한다.반면
multipart/form-data는 이러한 바이너리 데이터를 별도의 인코딩 없이 그대로 전송할 수 있기 때문에 더욱 효율적이다.
MultipartFile
이렇게 클라이언트가 multipart/form-data 형식으로 업로드 한 파일이 Spring Boot 를 통해 구현된 서버에 전송되게 되면 DispatcherServlet 가 해당 요청을 처리하고, MultipartResolver 를 통해 컨트롤러로 요청을 전달하게 된다.
그리고 이렇게 컨트롤러로 전달된 파일을 다루기 위해 Spring 에서는 MultipartFile 인터페이스를 제공한다.
MultipartFile 의 주석을 읽어보면 다음과 같다.
A representation of an uploaded file received in a multipart request.
The file contents are either stored in memory or temporarily on disk. In either case, the user is responsible for copying file contents to a session-level or persistent store as and if desired. The temporary storage will be cleared at the end of request processing.
즉, multipart/form-data 로 보낸 클라이언트 파일을 다루기 위해 MultipartFile 인터페이스를 사용하면 된다. 그리고 해당 파일이 처리되는 동안에는 서버에 임시적으로 저장하고 있다가 요청이 끝나면 삭제하게 된다.
따라서 MultipartFile 을 통해 요청된 파일을 서버의 파일 시스템을 이용하여 관리하기 위해서는 Java의 File 로 변환하여 다루게 된다.
