- ···
- 26.
[멀티캠퍼스] 풀스택 개발자 아카데미 (26) - Spring Boot(2) - 27.[멀티캠퍼스] 풀스택 개발자 아카데미 (27) - Spring Boot(3)현재
- 28.
[멀티캠퍼스] 풀스택 개발자 아카데미 (28) - Spring Boot & JWT(1) - ···
1. 웹 애플리케이션
지난 글까지 우리는 스프링 부트의 자동 설정과 간결한 구조를 통해 MVC 패턴을 구축하고 데이터베이스를 연동하는 방법을 알아보았다. 이제 웹 애플리케이션의 핵심 기능을 거의 다 갖추었지만, 사용자 경험(UX)을 한 단계 더 끌어올리기 위한 마지막 조각이 남아있다. 바로 파일 업로드와 RESTful 통신이다.
쇼핑몰에서 상품 이미지를 등록하거나, SNS에 사진을 올리는 기능은 현대 웹에서 빠질 수 없는 요소이다. 과거 Legacy Spring에서는 파일 업로드를 위해 commons-fileupload 라이브러리를 별도로 추가하고 MultipartResolver 빈을 직접 등록해야 하는 번거로움이 있었다. 하지만 스프링 부트는 이마저도 자동화하여 매우 간단하게 처리할 수 있도록 지원한다.
이번 글에서는 MultipartFile 인터페이스를 활용하여 파일을 업로드하는 방법을 알아보고, 파일명 중복 방지를 위한 UUID 활용법, 그리고 업로드된 이미지를 웹에서 바로 볼 수 있도록 하는 외부 경로 매핑 설정(WebConfig)을 다룬다. 나아가, 화면 전환 없이 파일을 업로드하고 결과를 바로 확인하는 Ajax 기반의 REST API 파일 업로드 기능을 구현하며 시리즈를 마무리한다.
2. Spring Boot 파일 업로드의 기초
2.1. MultipartFile과 자동 설정
스프링 부트(Spring Boot)는 웹 스타터(spring-boot-starter-web)에 파일 업로드를 위한 서블릿 표준 라이브러리를 이미 내장하고 있다. 따라서 별도의 라이브러리 추가나 빈 등록 없이, 컨트롤러에서 MultipartFile 타입의 파라미터를 받는 것만으로 업로드된 파일을 처리할 수 있다.
클라이언트가 multipart/form-data 형식으로 전송한 데이터는 DispatcherServlet 내부의 멀티파트 리졸버에 의해 해석되어 MultipartFile 객체로 변환되고 컨트롤러에 주입된다.
2.2. 용량 제한 설정: application.properties
파일 업로드 시 가장 주의해야 할 점은 용량 제한이다. 너무 큰 파일 업로드를 허용하면 서버의 디스크 공간이 부족해지거나 네트워크 대역폭을 과도하게 점유할 수 있다. 스프링 부트는 기본적으로 파일당 1MB, 전체 요청당 10MB로 제한하고 있다. 이를 변경하려면 application.properties를 수정한다.
(참고: 자료에서는 maxFileSize, maxRequestSize로 언급되었으나, 최신 스프링 부트 버전에 맞춰 표준 속성 키를 사용했다.)
3. 안전하고 체계적인 파일 저장 전략
3.1. 파일명 중복 방지
사용자가 업로드한 파일의 이름이 서버에 이미 존재하는 파일 이름과 같다면 어떻게 될까? 보통은 덮어씌워져 기존 파일이 유실되는 문제가 발생한다. 이를 방지하기 위해 원본 파일명 대신 고유한 식별자를 생성하여 저장해야 한다.
가장 널리 쓰이는 방법은 UUID(Universally Unique Identifier) 를 사용하는 것이다. UUID는 128비트의 수로, 중복될 확률이 거의 없는 문자열을 생성해준다.
3.2. 외부 경로 매핑
파일을 프로젝트 내부(src/main/webapp/...)에 저장하면 배포 시 파일이 사라지거나 관리가 어려워진다. 따라서 실제 운영 환경에서는 로컬 디스크의 별도 경로(예: C:/uploads/) 나 클라우드 스토리지(S3 등)에 저장한다.
문제는 로컬 디스크의 C:/uploads/ 경로는 웹 브라우저가 직접 접근할 수 없는 보안 영역이라는 점이다. 이를 해결하기 위해 지난 글에서 배운 WebConfig 설정을 통해, 특정 URL 요청을 로컬 디스크 경로로 연결(매핑)해 주어야 한다.
이제 http://localhost:8080/upload/이미지.jpg로 요청하면 C:/spring_uploads/이미지.jpg가 보인다.
4. Ajax 비동기 파일 업로드 구현
이제 이론을 바탕으로 페이지 새로고침 없는 세련된 파일 업로드 기능을 구현해보자.
4.1. View: 파일 업로드 폼
form 태그의 enctype은 반드시 multipart/form-data여야 하지만, Ajax를 사용할 때는 FormData 객체가 이를 대신 처리해준다.
4.2. RestController
REST 컨트롤러를 작성하여 파일을 받고, 저장 후 변경된 파일명을 반환한다.
주요 포인트:
@RestController: 뷰 페이지가 아닌 파일명(String)을 그대로 응답 본문에 담아 보낸다.MultipartFile.transferTo(): 업로드된 임시 파일을 실제 목적지 경로로 이동(저장)시키는 가장 간편한 메소드이다. (자료에서는FileCopyUtils등을 언급했으나, 최신 방식인transferTo가 더 직관적이다.)- Ajax 설정:
processData: false,contentType: false설정은FormData를 이용해 파일을 전송할 때 반드시 필요하다.
4.3. 실행 결과 확인
- 애플리케이션을 실행한다.
- 브라우저에서
http://localhost:8080/upload.jsp(컨트롤러를 통해 뷰를 띄운다면 해당 경로)에 접속한다. - 파일을 선택하고 '업로드' 버튼을 누른다.
- 페이지 깜빡임 없이 "업로드 성공!" 알림창이 뜨고, 하단에 이미지가 바로 표시되는지 확인한다.
- 실제
C:/spring_uploads/폴더에UUID_파일명.jpg형태로 파일이 저장되었는지 확인한다.
5. 마무리하며
이번 글에서는 스프링 부트의 강력함이 가장 잘 드러나는 파일 업로드 기능을 다루었다. 복잡한 설정 없이 MultipartFile 하나로 처리가 가능하다는 점은 레거시 방식과 비교했을 때 큰 장점이다.
특히 Ajax와 연동하여 비동기 업로드를 구현하는 실습은 최근 웹 트렌드인 SPA(Single Page Application) 개발의 기초가 되는 중요한 기술이다. 또한, 보안과 관리를 위해 파일을 외부 경로에 저장하고 WebConfig로 매핑하는 기법은 실무에서 반드시 사용되는 패턴이므로 잘 숙지해두어야 한다. UUID를 이용한 파일명 중복 방지 역시 필수적인 테크닉이다.
이로써 Multicampus의 Spring 개발자 과정을 모두 훑어보았다.