개발/Spring

Spring Boot에서 파일 업로드 구현하기(Ajax File upload)

피터JK 2025. 2. 13. 16:01
728x90

 

1. 서버 (Spring Boot) 설정

먼저 Spring Boot 서버를 설정합니다. 이 서버는 클라이언트로부터 Ajax 요청을 받아 파일을 업로드하는 기능을 처리합니다.

1.1 Controller 코드

FileUploadController 클래스는 Ajax 요청을 처리하며, 업로드된 파일을 서버에 저장합니다.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.UUID;

@RestController
public class FileUploadController {

    @Value("${file.upload-dir}")
    private String uploadDir;

    @Value("${file.allowed-extensions}")
    private String allowedExtensions;

    @PostMapping("/file/uploadFile")
    public String handleFileUpload(@RequestParam("files") MultipartFile[] files) {
        if (files.length == 0 ) {
            return "파일이 선택되지 않았습니다.";
        }

        List<String> uploadedFiles = new ArrayList<>();
        List<String> failedFiles = new ArrayList<>();
        List<String> rejectedFiles = new ArrayList<>();

        // 허용된 확장자 목록을 ',' 기준으로 분리하여 리스트로 변환
        List<String> allowedList = Arrays.asList(allowedExtensions.split(","));

        // 여러 파일 처리
        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                continue;
            }

            String fileName = file.getOriginalFilename();
            if (fileName == null) continue;

            // 파일 확장자 추출
            String fileExtension = getFileExtension(fileName);

            // 허용된 확장자 확인
            if (!allowedList.contains(fileExtension.toLowerCase())) {
                rejectedFiles.add(fileName);
                continue;
            }

            // 파일명 추출 후 UUID로 고유한 파일명 생성
            String uniqueFileName = UUID.randomUUID().toString() + "." + fileExtension;

            // 파일 저장 경로 설정
            try {
                String filePath = Paths.get(uploadDir, uniqueFileName).toString();
                File dest = new File(filePath);
                file.transferTo(dest);
                uploadedFiles.add(fileName);
            } catch (IOException e) {
                failedFiles.add(fileName);
            }
        }

        StringBuilder sb = new StringBuilder();
        if (!uploadedFiles.isEmpty()) {
            sb.append("업로드 성공: ").append(String.join(", ", uploadedFiles));
        }
        if (!failedFiles.isEmpty()) {
            sb.append("업로드 실패: ").append(String.join(", ", failedFiles));
        }
        if (!rejectedFiles.isEmpty()) {
            sb.append("허용되지 않은 확장자: ").append(String.join(", ", rejectedFiles));
        }

        return sb.toString();
    }

    // 파일 확장자 추출 메서드
    private String getFileExtension(String fileName) {
        int lastIndex = fileName.lastIndexOf(".");
        if (lastIndex == -1) {
            return ""; // 확장자가 없는 경우
        }
        return fileName.substring(lastIndex + 1);
    }
}

1.2 application.properties 설정

application.properties 파일에서 파일 업로드 디렉토리와 기타 설정을 해줍니다.

# 파일 업로드 경로
file.upload-dir=C:/upload
file.allowed-extensions=jpg,png,txt,pdf

2. 클라이언트 (HTML + jQuery + Ajax)

클라이언트 측에서는 jQuery를 사용해 Ajax 요청을 보냅니다. 파일을 선택하고 업로드 버튼을 클릭하면 Ajax를 통해 서버에 파일을 비동기적으로 업로드합니다.

2.1 HTML 코드

upload.html 파일을 작성하여 파일 선택 및 업로드 버튼을 구현합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>파일 업로드</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <h2>파일 업로드</h2>
    <!-- 파일 업로드 폼 -->
    <form id="uploadForm" method="post" enctype="multipart/form-data">
    	<input type="file" id="fileInput" required multiple name="files">
	    <button id="uploadButton">업로드</button>
	</form>
    <!-- 결과 메시지 표시 영역 -->
    <div id="result"></div>

    <script>
        $(document).ready(function() {
            $("#uploadButton").click(function(event) {
 	            event.preventDefault();
                
                var fileInput = $("#fileInput")[0];
                var formData = new FormData($('#uploadForm')[0]);
                formData.append("file", fileInput.files[0]);

                // Ajax 요청 보내기
                $.ajax({
                    url: "/file/uploadFile",  // 파일을 처리할 서버 URL
                    type: "POST",
                    data: formData,
                    contentType: false,  // 자동으로 콘텐츠 타입을 설정하지 않도록 설정
                    processData: false,  // jQuery가 데이터를 처리하지 않도록 설정
                    success: function(response) {
                        // 업로드 성공 시 메시지 출력
                        $("#result").html("<p>" + response + "</p>");
                    },
                    error: function(xhr, status, error) {
                        // 업로드 실패 시 메시지 출력
                        $("#result").html("<p>업로드 실패: " + error + "</p>");
                    }
                });
            });
        });
    </script>
</body>
</html>
 

2.2 코드 설명

  • $("#uploadButton").click() 이벤트 리스너를 통해 업로드 버튼 클릭 시 FormData 객체를 생성하여 파일을 첨부합니다.
  • $.ajax()를 사용해 POST 요청을 보냅니다. 이때 contentType: false와 processData: false는 jQuery가 요청 데이터를 자동으로 처리하지 않도록 하는 옵션입니다. 이는 FormData를 사용해 파일을 전송하기 위해 필요합니다.
  • 업로드가 완료되면 성공 메시지 또는 오류 메시지를 HTML 페이지에 표시합니다.

3. 실행 및 테스트

  1. Spring Boot 애플리케이션을 실행합니다.
mvn spring-boot:run
  1. 브라우저에서 http://localhost:8080을 열고, 파일을 선택한 후 업로드 버튼을 클릭합니다.
  2. 파일이 서버에 업로드되면 업로드 결과 메시지가 화면에 표시됩니다.

4. 마무리

이번 글에서는 Spring BootjQuery + Ajax를 사용하여 파일을 비동기적으로 업로드하는 방법을 소개했습니다. 이 방식은 페이지를 새로 고침하지 않고도 파일을 서버로 전송할 수 있어 사용자 경험을 향상시킬 수 있습니다.

📚 관련 자료

 

 

- Ajax Flie download

 

Ajax File download(Spring boot)

jQuery를 사용하여 POST 방식으로 파일 다운로드하는 방법을 설명해 드리겠습니다.일반적인 AJAX 요청과 다르게, 파일 다운로드 시 브라우저에서 자동으로 다운로드되도록 처리해야 합니다.📝 구

piterjk.tistory.com

 

728x90