기록은 기억을 이기고 시간보다 오래 남는다.

에러일지

MaxUploadSizeExceededException: 원인과 해결 방법

준_준 2025. 1. 16. 10:28

Spring Boot에서 파일 업로드를 지원할 때 기본적으로 설정된 업로드 크기 제한(1MB 내외)을 초과하면 MaxUploadSizeExceededException이 발생. 여기서는 이 예외가 발생하는 이유와 해결 방법을 기술함


예외 발생 원인

  1. Spring 설정값 초과
    • spring.servlet.multipart.max-file-size 또는 spring.servlet.multipart.max-request-size 설정값보다 큰 파일을 업로드하려고 하면 발생.
  2. 서버 컨테이너의 업로드 제한
    • 톰캣(Tomcat), 언더토우(Undertow) 등의 서버 컨테이너가 자체적으로 업로드 크기를 제한하는 경우에도 예외가 발생.
  3. ExceptionHandler 동작 이전 차단
    • 파일이 업로드 크기 제한을 초과하면 Spring이 요청을 아예 처리하지 않아서 @ExceptionHandler로 예외를 잡을 수 없게 됨.

예외 발생 결과

  • HTTP 상태 코드 400 또는 500 반환
    • 클라이언트에서 400 Bad Request 또는 500 Internal Server Error를 확인할 수 있어.
  • 서버 로그에 예외 메시지 출력
    • 예: Maximum upload size exceeded.

해결 방법

1. Application 설정값 조정

파일 업로드 크기를 늘리려면 application.properties 또는 application.yml에 다음과 같이 설정 가능.

application.properties:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

application.yml:

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  • max-file-size: 단일 파일 크기 제한.
  • max-request-size: 한 요청에 포함된 전체 파일 크기 제한.

2. 톰캣 업로드 제한 조정

Spring Boot가 톰캣을 내장 서버로 사용하는 경우, application.properties에 다음 설정을 추가

server.tomcat.max-swallow-size=10MB

기본값은 -1(제한 없음)으로 설정되어 있지만, 명시적으로 지정해주는 것이 좋음.

3. 예외 처리 핸들러 추가

업로드 제한을 초과했을 때 사용자에게 적절한 메시지를 반환하려면 @ControllerAdvice@ExceptionHandler를 사용.

예제 코드:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.http.ResponseEntity;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseEntity<String> handleMaxSizeException(MaxUploadSizeExceededException ex) {
        return ResponseEntity.badRequest().body("파일 크기가 너무 큽니다. 최대 업로드 크기를 확인하세요.");
    }
}

또한, 다음 설정을 추가해야 예외 핸들러가 동작하도록 할 수 있어:

spring.servlet.multipart.resolve-lazily=true

4. Nginx 프록시 설정 변경

Nginx를 사용하는 경우 client_max_body_size를 설정해야 해. 서버 설정 파일에 다음 줄을 추가:

http {
    client_max_body_size 10M;
}

5. Vue와 통합된 파일 업로드 처리

Vue에서 파일 업로드 요청:

async function uploadFile(file) {
  const formData = new FormData();
  formData.append('file', file);

  try {
    const response = await axios.post('/api/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
    console.log('파일 업로드 성공:', response.data);
  } catch (error) {
    console.error('파일 업로드 실패:', error.response.data);
  }
}

Spring Boot 파일 업로드 컨트롤러:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 파일 처리 로직 (저장 등)
            String fileName = file.getOriginalFilename();
            System.out.println("업로드된 파일 이름: " + fileName);
            return ResponseEntity.ok("파일 업로드 성공: " + fileName);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("파일 업로드 실패: " + e.getMessage());
        }
    }
}

주의사항

  1. 업로드 크기를 너무 크게 설정하면 서버 리소스가 낭비될 수 있어. 적절한 제한값을 설정.
  2. 운영 환경에서는 프론트엔드와 백엔드, 프록시(Nginx 등) 모두 일관되게 업로드 제한을 설정.

 

 

반응형