Spring Boot 파일 Upload Form 구현하기
form 데이터는 2가지로 구분된다.
- application/x-www-form-urlencoded
- multipart/form-data
여기서 application/x-www-form-urlencoded
는 일반적인 key-value
의 form 데이터 전송을 담당하고,
파일과 다양한 정보들을 함께 넘겨야 하기 때문에 multipart/form-data
를 사용한다.
multipart-form
form에서 enctype으로 multipart라고 명시한다.
<form action="/test" method="post" enctype="multipart/form-data">
...
</form>
enctype="multipart/form-data"
: 멀티파트로 form 데이터를 넘긴다는 뜻
multipart-form 예제
Request Header
POST / HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: __atuvc=34%7C7; permanent=0; _gitlab_session=226ad8a0be43681acf38c2fab9497240; __profilin=p%3Dt; request_method=GET
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
Content-Length: 554
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="text"
text default
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------9051914041544843365972754266--
Accept-Encoding: gzip, deflate
: 클라이언트 -> 웹서버에게 gzip 압축을 이해하고 해제할 수 있다고 서버에 알리는 것이다. (명시)
Response Header
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Content-Encoding: gzip
Server: GWS/2.1
Content-Length: 1865
Date: Thu, 14 Jul 2005 14:21:24 GMT
Response에서 결과물을 Content-Encoding: gzip
이런 식으로 서버 -> 클라이언트로 보내는 내용이 gzip 암호화 되어있다고 표기한다.
multipart/form-data
는 다른 여러 종류의 파일과 폼의 내용을 함께 전송 할 수 있다.기본 text인 key-value
-----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="text" text default
text file과 html
-----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="file1"; filename="a.txt" Content-Type: text/plain Content of a.txt. -----------------------------9051914041544843365972754266 Content-Disposition: form-data; name="file2"; filename="a.html" Content-Type: text/html
multi-part 업로드 파일 사이즈 제한
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
max-file-size
: 개별 파일 사이즈 제한max-request-size
: 한 Request 전체 파일 사이즈 제한
💥참고로 서버의 multipartForm 사용을 안한다고 끄는 기능도 있다.
실습
Upload
실제 경로 설정
- Upload가 되려면 저장공간이 필요하기 때문에, 실제 파일저장 경로를 설정해주어야 한다.
yml 파일
file.dir=/Users/study/file/
💥마지막에 /가 들어감
- Controller에서 기본 file경로를 설정해준다.
public class ServletUploadControllerV2 {
@Value("${file.dir}")
private String fileDir;
}
@Value("${file.dir}")
: properties, yml 등의 설정을 가져다 쓰는 방법
Front의 Form에서 multiPartForm으로 itemName,file을 보낸 상황
@PostMapping("/upload")
public String saveFile(@RequestParam String itemName,
@RequestParam MultipartFile file, HttpServletRequest request) throws IOException {
log.info("request={}", request);
log.info("itemName={}", itemName);
log.info("multipartFile={}", file);
if (!file.isEmpty()) {
String fullPath = fileDir + file.getOriginalFilename();
log.info("파일 저장 fullPath={}", fullPath);
file.transferTo(new File(fullPath));
}
return "upload-form";
}
@RequestParam String itemName
: Request의 itemName을 받는다.@RequestParam MultipartFile file
: Spring에서 지원하는MultipartFile
인터페이스로 file들을 받을 수 있다.file.getOriginalFilename()
: file의 이름을 반환해준다. 이름 그대로 저장하는 경로 설정에 사용file.transferTo
: 실 파일 저장
💥 운영에서는 보통 db서버에 blob로 저장하여 db에 저장해둔다.
'스프링 > MVC' 카테고리의 다른 글
[MVC 기초]Spring Formatter Date, Number 원하는 포맷으로 변환하기 (0) | 2022.07.26 |
---|---|
[MVC 기초] Custom 객체 Converter 생성, ConversionService에 등록해 자유롭게 변환하기 (+thymeleaf에서 변환법) (0) | 2022.07.25 |
[MVC 기초] API 예외 처리 @ExceptionHandler + 스프링 Resolver 동작 원리 (0) | 2022.07.07 |
[MVC 기본] 공통 관심사항을 처리하는 방법 (Servlet Filter, Spring Interceptor를 구현하며) (0) | 2022.06.06 |
[MVC 기초] 패키지 구조 설계 domain vs web package (0) | 2022.05.29 |