Spring Boot로 파일 업로드와 다운로드 구현
✈️ Spring Boot로 파일 업로드와 다운로드 구현
🎯 개요
Spring Boot로 파일 업로드와 다운로드 기능 구현 JDK21과 Gradle 환경에서 MultipartFile과 Resource로 파일 처리 IntelliJ Ultimate로 로컬 테스트와 디버깅 편리
📋 목록
- 파일 업로드와 다운로드란?
- 준비 항목
- 구현 단계
- 로컬 실행과 디버깅
- 실무 팁과 주의사항
✏️ 파일 업로드와 다운로드란?
파일 업로드 정의
웹에서 파일을 서버로 전송하는 기능 MultipartFile로 파일 이름, 크기, 형식 관리
파일 다운로드 정의
서버에서 파일을 사용자에게 제공하는 기능 Resource로 파일 준비와 다운로드 지원
💡왜 필요하나?
Spring Boot 프로젝트에서 이미지나 문서 처리로 기능 확장 Gradle 빌드와 application.yml로 설정 간소화
✏️ 준비 항목
- JDK21: java.net에서 다운로드
- IntelliJ Ultimate: 개발 환경 구성
- Spring Initializr: start.spring.io로 프로젝트 생성
- Gradle: 빌드 툴로 의존성 관리
- Thymeleaf: HTML 템플릿 엔진
💡특이사항
Gradle 8.x 이상으로 JDK21 호환성 확보 application.yml로 파일 크기 제한 설정
✏️ 구현 단계
1단계: 프로젝트 설정
start.spring.io로 Spring Web, Thymeleaf 선택 후 다운로드 build.gradle에 의존성 확인
plugins {
id 'org.springframework.boot' version '3.4.5'
id 'io.spring.dependency-management' version '1.1.7'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '21'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
}
application.yml에 업로드 설정 추가
spring:
application:
name: file-app
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
server:
port: 8080
2단계: 파일 업로드 구현
컨트롤러에 업로드 메서드 추가
@Controller
public class FileController {
private static String UPLOAD_DIR = "uploads/";
@GetMapping("/")
public String index() {
return "index";
}
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file, RedirectAttributes attributes) {
if (file.isEmpty()) {
attributes.addFlashAttribute("message", "파일을 선택하세요");
return "redirect:/";
}
try {
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOAD_DIR + file.getOriginalFilename());
Files.createDirectories(path.getParent());
Files.write(path, bytes);
attributes.addFlashAttribute("message", "파일 업로드 성공: " + file.getOriginalFilename());
} catch (IOException e) {
attributes.addFlashAttribute("message", "파일 업로드 실패");
}
return "redirect:/";
}
}
Thymeleaf 템플릿으로 업로드 폼
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>파일 업로드/다운로드</title>
</head>
<body>
<h1>파일 업로드</h1>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">업로드</button>
</form>
<p th:if="${message}" th:text="${message}"></p>
</body>
</html>
3단계: 파일 다운로드 구현
컨트롤러에 다운로드 메서드 추가
@GetMapping("/download/{filename:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String filename) {
try {
Path file = Paths.get(UPLOAD_DIR + filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() && resource.isReadable()) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
return ResponseEntity.notFound().build();
} catch (Exception e) {
return ResponseEntity.badRequest().build();
}
}
템플릿에 다운로드 링크 추가
<a th:href="@{/download/{filename}(filename='example.txt')}" th:text="'다운로드'"></a>
💡특이사항
IntelliJ Ultimate로 MultipartFile 디버깅 편리 uploads 폴더 생성으로 파일 저장 위치 확인
✏️ 로컬 실행과 디버깅
- Gradle로 빌드 및 실행:
./gradlew bootRun
- http://localhost:8080 접속
- 파일 선택 후 업로드
- 다운로드 링크 클릭으로 파일 확인
- IntelliJ 콘솔 로그로 에러 디버깅
- 파일 형식 제한 추가:
if (!file.getContentType().startsWith("image/")) { attributes.addFlashAttribute("message", "이미지만 허용"); return "redirect:/"; }
💡특이사항
브라우저 개발자 도구로 네트워크 탭 점검 application.yml로 파일 크기 조정
✏️ 실무 팁과 주의사항
파일 처리 팁
- 간단 시작: 단일 파일 업로드 테스트
- 보안 주의: 파일 형식과 크기 제한 필수
- 에러 처리: 사용자 메시지 출력
- 확장 가능: 다중 파일 업로드나 S3 연동
- Thymeleaf 활용: 동적 파일 목록 표시
주의사항
- 파일 저장 위치: uploads 폴더 권한 확인
- 의존성 호환: Gradle 빌드 시 spring-boot-starter-web 버전 점검
- 로그 확인: IntelliJ 콘솔로 업로드 실패 디버깅
- 테스트: 로컬 환경에서 업로드와 다운로드 동작 확인
댓글남기기