본문 바로가기
1인개발자에서 살아남는법!/시리즈

[#6 Spring boot] Spring Boot + Ajax 파일 업로드 가이드

by Alan__kang__morlang 2025. 6. 2.
반응형

안녕하세요 오늘은 Spring Boot + Ajax 파일 업로드로 마이그레이션 하는 과정에서 기본적인 틀을 잡아보고자 합니다. 

 

시니어 개발자들의 이미지 파일 처리 방식 비교

이미지 파일 처리에 대해 시니어 개발자들은 아래와 같은 두 가지 주요 방식을 선호합니다:

  1. Form 태그 일괄 전송 방식:
    • 전통적인 방식으로, form 전체 데이터를 서버로 전송
    • 서버에서 파일 저장과 데이터 처리 동시 진행
    • 간단하지만 UX가 떨어지고 대용량 처리에 부담
  2. Ajax 개별 업로드 방식:
    • 사용자가 파일 선택 시 Ajax로 비동기 전송
    • 진행률 표시, 실패 시 재시도 등 UX 개선 가능
    • 확장성과 유지보수에 유리, Cloud Storage 연동 용이

이 프로젝트에서는 Ajax 개별 업로드 방식을 선택하여 구현했습니다.

1️⃣ 문제 상황

Spring Boot로 마이그레이션하면서 기존 폼(form) 전송 방식 대신, Ajax를 활용하여 이미지 업로드를 구현하고자 했습니다.

기존에는 form 태그 내 input file로 파일을 선택하고, 전송 버튼 클릭 시 모든 데이터를 함께 전송했습니다.

2️⃣ Spring Boot 업로드 Controller

@RestController
@RequestMapping("/upload")
public class FileUploadController {

    private final String uploadDir = "/your/upload/path/";

    @PostMapping("/image")
    public ResponseEntity<?> uploadImage(@RequestParam("file") MultipartFile file) {
        try {
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String uniqueFileName = UUID.randomUUID() + extension;

            File dest = new File(uploadDir + uniqueFileName);
            file.transferTo(dest);

            String fileUrl = "/uploaded/images/" + uniqueFileName;
            return ResponseEntity.ok(Map.of("url", fileUrl));
        } catch (IOException e) {
            return ResponseEntity.status(500).body(Map.of("error", "File upload failed"));
        }
    }
}
    

3️⃣ Frontend (jQuery + Ajax) 코드

이미지 클릭 시 input[type=file]이 동적으로 생성되고, 파일 선택 후 Ajax로 업로드되는 코드입니다.

function clickImage(obj) {
    $(obj).siblings('input[type="file"]').remove();
    var $fileInput = $('', {type:'file', name:'file', style:'display:none'});
    $(obj).parent().append($fileInput);
    $fileInput.click();

    $fileInput.on('change', function(event) {
        var file = event.target.files[0];
        if (!file) return;

        if (file.size > 10 * 1024 * 1024) { // 10MB 제한
            alert('파일 크기가 너무 큽니다.');
            return;
        }

        var reader = new FileReader();
        reader.onload = function(e) {
            $(obj).attr("src", e.target.result); // 미리보기
        };
        reader.readAsDataURL(file);

        var formData = new FormData();
        formData.append('file', file);

        $.ajax({
            url: '/upload/image',
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(response) {
                console.log('업로드 성공:', response.url);
            },
            error: function(xhr) {
                console.error('업로드 실패', xhr);
            }
        });
    });
}
    

4️⃣ 업로드 용량 초과 오류 해결

업로드 시 MaxUploadSizeExceededException 오류가 발생했는데, 이는 Spring Boot 기본 업로드 제한 때문입니다.

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 20MB
    

5️⃣ 결론 및 권장

  • Ajax 업로드는 사용자 경험을 개선하고 유지보수가 용이
  • 업로드 전에 JS에서 용량 체크를 권장
  • Spring Boot Controller는 MultipartFile로 처리하고, 파일 저장 후 URL 반환
  • 대규모 서비스라면 AWS S3, Cloudinary 연동을 고려

📌 주니어 개발자도 이해할 수 있도록 최대한 상세히 정리했습니다!

 

반응형