728x90
파일 업로드
-> 일반적으로 사용하는 HTML Form을 통한 파일 업로드를 이해하려면 먼저 폼을 전송하는 두가지 방식의 차이를 이해해야한다.
- application/x-www-form-urlencoded
- multipart/form-data

application/x-www-form-urlencoded 방식은 HTML 폼 데이터를 서버로 전송하는 가장 기본적인 방법이다.
Form 태그에 별도의 enctype옵션이 없으면 웹 브라우저는 요청 HTTP메시지의 헤더에Content-Type: application/x-www-form-urlencoded을 추가한다.
파일을 업로드 하려면 파일은 문자가 아니라 바이너리 데이터를 전송해야 한다. 문자를 전송하는 이 방식으로 파일을 전
송하기는 어렵다. 그리고 또 한가지 문제가 더 있는데, 보통 폼을 전송할 때 파일만 전송하는 것이 아니라는 점이다. 다음 예를 보자.
- 이름
- 나이
- 첨부파일
여기에서 이름과 나이도 전송해야 하고, 첨부파일도 함께 전송해야 한다. 문제는 이름과 나이는 문자로 전송하고, 첨부 파일은 바이너리로 전송해야 한다는 점이다. 여기에서 문제가 발생한다. 문자와 바이너리를 동시에 전송해야 하는 상황 이다.
이 문제를 해결하기 위해 HTTP는 multipart/form-data 라는 전송 방식을 제공한다.
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.6'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.changddao'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
}
tasks.named('test') {
useJUnitPlatform()
}
multipart 사용 옵션
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
큰 파일을 무제한 업로드하게 둘 수는 없으므로 업로드 사이즈를 제한할 수 있다. 사이즈를 넘으면 예외( SizeLimitExceededException )가 발생한다.max-file-size : 파일 하나의 최대 사이즈, 기본 1MBmax-request-size : 멀티파트 요청 하나에 여러 파일을 업로드 할 수 있는데, 그 전체 합이다. 기본 10MB
스프링과 파일 업로드
-> 스프링은 MultipartFile 이라는 인터페이스로 멀티파트 파일을 매우 편리하게 지원한다.
application.properties
logging.level.org.apache.coyote.http11=debug
file.dir=/Users/changhoyoun/file/
spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB
SpringUploadController
package com.changddao.springupload.controller;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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 org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Slf4j
@Controller
@RequestMapping("/spring")
public class SpringUploadController {
@Value("${file.dir}")
private String fileDir;
@GetMapping("/upload")
public String newFile() {
return "upload-form";
}
@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";
}
}
- 위의 코드를 보면 application.properties 파일에 지정해둔 file.dir 값을 Controller에서 @Value 에노테이션을 이용하여 값을 가지고오고 있다.
- 주의*
- 꼭 해당 경로에 실제 폴더를 미리 만들어두자.
application.properties에서 설정할 때 마지막에/(슬래시)가 포함된 것에 주의하자.
- @RequestParam MultipartFile file
- 업로드하는 HTML Form의 name에 맞추어 @RequestParam을 적용하면 된다.
MultipartFile 주요 메서드file.getOriginalFilename(): 업로드 파일 명file.transferTo(...): 파일 저장 - Spring이용하여 File 업로드 하기 및 File Download(2)에서 실습을 진행해보자
- 업로드하는 HTML Form의 name에 맞추어 @RequestParam을 적용하면 된다.
'Spring & SpringBoot' 카테고리의 다른 글
| 스프링부트를 사용해야 하는 이유 (0) | 2023.12.04 |
|---|---|
| Spring이용하여 File 업로드 하기 및 File Download(2) (0) | 2023.12.03 |
| Spring Bean @Validation (2) | 2023.12.03 |
| 스프링 빈의 Life Cycle (1) | 2023.12.02 |
| 스프링 싱글톤 패턴 (1) | 2023.12.02 |