1. 개요
- 스프링에서 제공하는
MultipartFile
이라는 인터페이스를 통해서 파일업로드 하는 방법에 대해서 알아보자. - 예제는 MVC(thymleafe)를 통한, 간단한 파일 업로드이고, 자신의 홈디렉토리에 저장하는 것을 구현한다.
2. 파일 업로드하는 FileService
@Service
public class FileService {
// application.properties 에 app.upload.dir을 정의하고, 없는 경우에 default 값으로 user.home (System에 종속적인)
@Value("${app.upload.dir:${user.home}}")
private String uploadDir;
public void fileUpload(MultipartFile multipartFile) {
// File.seperator 는 OS종속적이다.
// Spring에서 제공하는 cleanPath()를 통해서 ../ 내부 점들에 대해서 사용을 억제한다
Path copyOfLocation = Paths.get(uploadDir + File.separator + StringUtils.cleanPath(multipartFile.getOriginalFilename()));
try {
// inputStream을 가져와서
// copyOfLocation (저장위치)로 파일을 쓴다.
// copy의 옵션은 기존에 존재하면 REPLACE(대체한다), 오버라이딩 한다
Files.copy(multipartFile.getInputStream(), copyOfLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
throw new FileStorageException("Could not store file : " + multipartFile.getOriginalFilename());
}
}
}
스프링에서 제공하는 MultipartFile
이라는 인터페이스를 이용해서, HTTP multipart 요청을 처리한다.
MultipartFile 요청은 큰 파일을 청크 단위로 쪼개서 효율적으로 파일 업로드 할 수 있게 해준다.
MultipartFile 인터페이스를 열어보면 다음과 같이 나와있다.
A representation of an uploaded file received in a multipart request.
이제, 다시 본로으로 돌아와서 실제 위의 작성한 코드를 살펴보면
Paths.get() 메서드를 통해서 저장할 위치(copyOfLocation)을 지정한다. 여기서 중요한 것은 File.seperator
가 OS 종속적으로 mac이나 리눅스 계열에서는 /
윈도우에서는 \
구분자를 나타낸다. 또한, StringUtils.cleanPath
를 사용한다.
그리고, Files.copy()메서드를 통해서 multipartFile의 inputstream을 얻어서 위에서 지정한 copyOfLocation에 파일을 쓴다. 정확히 Files.copy()메서드의 정의를 살펴보면 다음과 같다.
Copies all bytes from an input stream to a file. On return, the input stream will be at end of stream. input stream으로 얻은 모든 bytes 들을 file로 copy한다.
3. FileController
@Controller
public class FileController {
@Autowired
private FileService fileService;
@GetMapping
public String index(){
return "upload";
}
@PostMapping("/upload")
public String fileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
fileService.fileUpload(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
4. upload.html 파일
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<h1>File Upload Example</h1>
<form method="post" th:action="@{/upload}" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
여기서는 form 태그에 input type을 file로 받아서, form을 submit하면 FileController
에 정의했던 API를 타게 된다.
중요한 건 input의 name를 file
로 한 부분이 FileController
의 @ReuqestParam("file")
이 부분과 일치해야 한다.
📚 Related Posts
- Spring WebFlux 테스트 방법
- Spring과 MongoDB 연동 실전 가이드
- SpringBoot, MongoDB 시작하기
- Spring Boot 서버 타임존 설정 방법
- SpringBoot CommandLineRunner, ApplicationRunner 초기화 방법
- Jackson, LocalDateTime Serialization, Deserialization 이슈
- Spring Boot, Dockerfile로 이미지 생성, 배포하기
- SpringBoot RabbitMQ 연동하기
- Junit5 정리
- Spring Sentry(에러 트래킹 서비스) 적용하기
- [Spring] 빈 주입하는 방법 && Best Practice
- Thymeleaf 실무에서 자주 사용하는 것들
- Thymeleaf Collection 정보 화면에 렌더링하기
- Spring, JPA를 이용한 REST API 만들기
- [Spring] MultipartFile을 이용한 파일 업로드
- [Spring] 모델 검증(validation)
- [Spring]HandlerMethodArgumentResolver 인터페이스
- [Spring] DispatcherServlet에 대해서 알아보자
- [Spring] MVC 만들어 보기
- [Spring] 메세지 컨버터
- [Spring] MVC 살펴보기
- [Spring] @ConfigurationProperties를 이용해서 properties값들을 클래스로 관리하기
- [Spring] Profile 설정하기
- [Spring] SpringApplication를 통한 코딩
- [Spring Boot] 스프링 부트 3가지 특징
- [Spring] @SpringBootAppllication 어노테이션에 대한 고찰
- [Spring] bean circular dependencies (빈 순환 참조)
- [Spring]Bean에 대해서 알아보자
- SpringBoot, JPA, H2를 이용한 간단한API 작성
- [Spring] Spring Data Common 프로젝트 살펴보기