Multipart Resolver

2025. 2. 28. 02:26Spring Framework/Web on Servlet Stack

Spring MVC에서 파일 업로드 및 멀티파트 데이터 처리를 위해 MultipartResolver를 사용합니다.
MultipartResolvermultipart/form-data 요청을 파싱하고, 업로드된 파일을 다룰 수 있도록 도와주는 인터페이스입니다.

1. MultipartResolver 개념

웹 애플리케이션에서 파일 업로드는 일반적인 application/x-www-form-urlencoded 요청과 다르게 처리됩니다.
파일 업로드 요청은 multipart/form-data 형식으로 전송되며, 이를 파싱해야만 개별 파일과 폼 데이터를 사용할 수 있습니다.

Spring MVC에서는 MultipartResolver를 사용하여 multipart 요청을 자동으로 파싱하고,
기존 HttpServletRequestMultipartHttpServletRequest로 변환하여 컨트롤러에서 쉽게 다룰 수 있도록 합니다.

📌 멀티파트 요청 처리 과정
1️⃣ 클라이언트가 multipart/form-data 요청(파일 업로드 포함)을 보냄.
2️⃣ MultipartResolver가 요청을 감지하고 파일을 파싱.
3️⃣ HttpServletRequestMultipartHttpServletRequest로 래핑하여 파일 및 폼 데이터를 제공.
4️⃣ 컨트롤러에서 MultipartFile을 통해 업로드된 파일을 처리 가능.

2. MultipartResolver의 종류

Spring 6.0에서는 표준 서블릿 기반의 StandardServletMultipartResolver만을 지원하며,
이전 버전에서 사용되던 CommonsMultipartResolver(Apache Commons FileUpload 기반)는 더 이상 지원되지 않습니다.

✅ 1. StandardServletMultipartResolver (Servlet 3.0+ 지원)

  • 서블릿 컨테이너의 디폴트 multipart 파서를 사용하여 파일을 처리하는 방식.
  • Spring Boot 및 최신 Spring MVC 애플리케이션에서 권장됨.
  • 서블릿 컨테이너마다 동작 방식이 다를 수 있음.

📌 설정 예제 (Java 기반)

@Bean
public StandardServletMultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

위 빈이 multipartResolver라는 이름으로 등록되면, DispatcherServlet이 자동으로 감지하여 적용합니다.

3. Servlet 컨테이너에서 멀티파트 요청 활성화

서블릿 컨테이너에서 멀티파트 요청을 지원하도록 설정해야 합니다.
이를 위해 @MultipartConfig를 사용하거나, web.xml에서 <multipart-config>를 추가해야 합니다.

✅ 1. Java 기반 설정 (MultipartConfigElement 사용)

AbstractAnnotationConfigDispatcherServletInitializer를 확장하여 서블릿 컨테이너 설정을 적용할 수 있습니다.

📌 예제: MultipartConfigElement를 통한 서블릿 등록

import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.ServletRegistration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        // 업로드 파일 저장 디렉터리 및 설정 적용
        registration.setMultipartConfig(new MultipartConfigElement("/tmp",
            10485760, // maxFileSize: 10MB
            20971520, // maxRequestSize: 20MB
            5242880   // fileSizeThreshold: 5MB
        ));
    }
}

📌 설명

  • /tmp 디렉토리를 파일 저장 위치로 설정.
  • maxFileSize = 10MB → 개별 파일 크기 제한.
  • maxRequestSize = 20MB → 전체 요청 크기 제한.
  • fileSizeThreshold = 5MB → 특정 크기 이상이면 디스크에 저장.

✅ 2. web.xml에서 <multipart-config> 설정

Spring Boot가 아닌 환경에서는 web.xml을 사용하여 설정할 수도 있습니다.

📌 예제: web.xml에서 설정

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>

    <multipart-config>
        <location>/tmp</location>
        <max-file-size>10485760</max-file-size>
        <max-request-size>20971520</max-request-size>
        <file-size-threshold>5242880</file-size-threshold>
    </multipart-config>
</servlet>

Java 설정과 동일한 기능을 web.xml에서 적용 가능.

4. 컨트롤러에서 파일 업로드 처리하기

설정이 완료되면, 컨트롤러에서 MultipartFile을 사용하여 업로드된 파일을 다룰 수 있습니다.

📌 예제: 파일 업로드 처리

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

    @PostMapping
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("파일이 비어 있습니다.");
        }

        try {
            // 파일 저장 (예제: 로컬 저장)
            Path path = Paths.get("/uploads/" + file.getOriginalFilename());
            Files.write(path, file.getBytes());

            return ResponseEntity.ok("파일 업로드 성공: " + file.getOriginalFilename());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("파일 업로드 실패");
        }
    }
}

📌 설명

  • @RequestParam("file") MultipartFile file을 사용하여 업로드된 파일을 받음.
  • 파일이 비어 있는 경우 오류 응답 반환.
  • /uploads/ 디렉터리에 업로드된 파일 저장.

5. 파일 업로드 폼 (HTML)

프론트엔드에서 파일을 업로드하려면 <form>enctype="multipart/form-data"로 설정해야 합니다.

📌 예제: HTML 파일 업로드 폼

<form method="POST" action="/upload" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">업로드</button>
</form>

➡ 브라우저에서 파일을 선택한 후, 서버로 업로드 요청을 보낼 수 있음.

6. 파일 업로드 시 발생할 수 있는 오류 및 해결 방법

🚨 1. StandardServletMultipartResolver가 동작하지 않는 경우

  • multipartResolver 빈이 누락되었을 가능성
    ➡ 해결: StandardServletMultipartResolverSpring 구성에서 명확히 등록
    @Bean
    public StandardServletMultipartResolver multipartResolver() {
      return new StandardServletMultipartResolver();
    }

🚨 2. org.springframework.web.multipart.MaxUploadSizeExceededException 발생

  • 업로드된 파일 크기가 maxFileSize 제한을 초과한 경우
    ➡ 해결: maxFileSize를 증가시키거나 클라이언트에서 파일 크기 제한

🚨 3. The request was rejected because no multipart boundary was found 오류

  • multipart/form-data 요청이 올바르게 설정되지 않은 경우
    ➡ 해결: form 태그에 enctype="multipart/form-data" 추가
    <form method="POST" action="/upload" enctype="multipart/form-data">

🚀 Summary

1️⃣ Spring MVC에서 파일 업로드 처리를 위해 MultipartResolver를 사용
2️⃣ Spring 6.0부터 CommonsMultipartResolver는 지원되지 않으며, StandardServletMultipartResolver만 사용 가능
3️⃣ Servlet 컨테이너에서 MultipartConfigElement 또는 <multipart-config> 설정이 필요
4️⃣ 컨트롤러에서 MultipartFile을 사용하여 업로드된 파일을 처리할 수 있음
5️⃣ HTML <form>에서는 반드시 enctype="multipart/form-data"를 설정해야 함

📌 Spring MVC에서 멀티파트 파일 업로드를 설정하면, 쉽고 효율적으로 파일을 처리할 수 있습니다! 🚀

 

출처 : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet/multipart.html

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

URI Links  (0) 2025.03.05
Logging  (1) 2025.02.28
View Resolution  (0) 2025.02.28
Exceptions  (0) 2025.02.28
Interception  (0) 2025.02.28