서블릿을 사용한 파일 업로드 구현 방법에 대해 알아보겠습니다. 스프링 부트 환경에서 멀티파트 폼 데이터를 처리하는 방법을 코드와 함께 살펴보겠습니다.
먼저 파일 업로드를 처리할 컨트롤러를 만들어보겠습니다.
package hello.upload.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.IOException;
import java.util.Collection;
@Slf4j
@Controller
@RequestMapping("/servlet/v1")
public class ServletUploadControllerV1 {
@GetMapping("/upload")
public String newFile() {
return "upload-form";
}
@PostMapping("/upload")
public String saveFileV1(HttpServletRequest request) throws ServletException, IOException {
log.info("request={}", request);
String itemName = request.getParameter("itemName");
log.info("itemName={}", itemName);
Collection<Part> parts = request.getParts();
log.info("parts={}", parts);
return "upload-form";
}
}
여기서 request.getParts()는 multipart/form-data 전송 방식에서 각각의 부분을 받아서 확인할 수 있게 해줍니다.
파일 업로드를 위한 HTML 폼을 다음과 같이 구현합니다.
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
</head>
<body>
<div class="container">
<div class="py-5 text-center">
<h2>상품 등록 폼</h2>
</div>
<h4 class="mb-3">상품 입력</h4>
<form th:action method="post" enctype="multipart/form-data">
<ul>
<li>상품명 <input type="text" name="itemName"></li>
<li>파일<input type="file" name="file"></li>
</ul>
<input type="submit"/>
</form>
</div>
</body>
</html>
# HTTP 요청 메시지 로그 확인을 위한 설정
logging.level.org.apache.coyote.http11=trace
# 파일 업로드 크기 제한
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
주의: 스프링 부트 3.2부터는
debug대신trace를 사용해야 로그가 출력됩니다.
파일 크기 제한
max-file-size: 단일 파일의 최대 크기 (기본 1MB)max-request-size: 전체 멀티파트 요청의 최대 크기 (기본 10MB)SizeLimitExceededException 발생멀티파트 처리 옵션
spring.servlet.multipart.enabled=true (기본값)멀티파트 옵션을 켜고 실행하면 다음과 같은 로그를 확인할 수 있습니다:
Content-Type: multipart/form-data; boundary=----xxxx
------xxxx
Content-Disposition: form-data; name="itemName"
Spring
------xxxx
Content-Disposition: form-data; name="file"; filename="test.data"
Content-Type: application/octet-stream
sdklajkljdf...
멀티파트 활성화 시 요청 객체가 StandardMultipartHttpServletRequest로 변환되어 처리되며, 파일과 폼 데이터를 정상적으로 처리할 수 있습니다.
enctype="multipart/form-data" 설정이 필요합니다.getParts()를 통해 업로드된 파일 정보를 얻을 수 있습니다.trace 레벨 설정이 필요합니다.