티스토리 뷰

먼저 읽어볼만한 글

라이브러리 종속성 추가

  • 프로젝트 루트의 /build.gradle 파일에 아래 내용을 추가한다.
dependencies {
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
    compile group: 'commons-io', name: 'commons-io', version: '2.6'
}
  • Multipart 처리와 직접적인 연관은 없지만 간결한 예제 소스 코드 작성을 위해 필요한 라이브러리를 프로젝트에 추가하였다.

환경설정

  • /src/main/resources/application-{profile}.yml 파일에 아래 내용을 추가한다.
spring:
  servlet:
    multipart:
      enabled: true
      location: ${java.io.tmpdir}
      max-file-size: 100KB
      max-request-size: 100KB
  • 파일 업로드 목적의 HTTP 요청시 헤더의 Content-Typemultipart/form-data이어야 한다.
  • Spring Boot에서 Multipart 요청을 처리하려면 multipartConfigElement, multipartResolver 이름의 빈이 애플리케이션 컨텍스트에 존재해야 한다. 애플리케이션 시작시 MultipartAutoConfiguration 클래스가 이 작업을 자동으로 수행한다.
  • multipart.maxFileSize는 업로드 가능한 최대 파일 크기, multipart.maxRequestSize는 업로드 가능한 총 요청 크기이다. 이 조건을 초과한 요청이 들어오면 MultipartException을 발생시킨다.

컨트롤러 작성

  • /src/main/java/com.jsonobject.example/AttachmentController.java 파일을 아래와 같이 작성한다.
package com.jsonobject.example;

import org.apache.commons.io.FilenameUtils
import org.apache.commons.lang3.RandomStringUtils
import org.springframework.http.ResponseEntity
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestPart
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import java.io.File

@RestController
@Validated
class AttachmentController {

    @PostMapping("/v1/attachments")
    fun uploadAttachment(@RequestPart sourceFile: MultipartFile): ResponseEntity<Void> {

        val sourceFileName = sourceFile.originalFilename
        val sourceFileNameExtension: String = FilenameUtils.getExtension(sourceFileName).toLowerCase()
        var destinationFile: File
        var destinationFileName: String
        do {
            destinationFileName = RandomStringUtils.randomAlphanumeric(32) + "." + sourceFileNameExtension
            destinationFile = File("C:/attachments/$destinationFileName")
        } while (destinationFile.exists())
        destinationFile.parentFile.mkdirs()
        sourceFile.transferTo(destinationFile)
        
        // sourceFile.getOriginalFilename()
        // sourceFile.getSize()
        // sourceFile.getContentType()

        return ResponseEntity.ok().build()
    }
}
  • sourceFile 이름으로 요청 받은 파일을 로컬 디스크에 복사 후 접근 가능한 URL을 포함한 파일 정보를 JSON으로 응답하는 간단한 기능이다.

  • MultipartFile.transferTo()는 요청 시점의 임시 파일을 로컬 파일 시스템에 영구적으로 복사하는 역할을 수행한다. 단 한번만 실행되며 두번째 실행부터는 성공을 보장할 수 없다. Embedded Tomcat을 컨테이너로 사용할 경우 DiskFileItem.write()가 실제 역할을 수행한다. I/O 사용을 최소화하기 위해 파일 이동을 시도하며, 이동이 불가능할 경우 파일 복사를 진행한다.

파일 업로드 테스트

  • 아래는 파일 업로드 테스트를 위해 간단히 작성한 HTML 코드이다.
<!DOCTYPE html>
<html>
<body>
    <form action="http://localhost:8080/v1/attachments" method="post" enctype="multipart/form-data">
        <input type="file" name="sourceFile" id="sourceFile">
        <input type="submit" name="submit" value="Upload File">
    </form>
</body>
</html>

참고 글

댓글
  • 프로필사진 비밀댓글입니다 2016.10.21 11:31
  • 프로필사진 최세민 Spring boot 환경에서 Unable to process parts as no multi-part configuration has been provided 에러나서 한참 찾았는데 겨우 해결했어요.

    @Bean
    public MultipartConfigElement multipartConfigElement() {
    MultipartConfigFactory factory = new MultipartConfigFactory();
    factory.setMaxFileSize("512MB");
    factory.setMaxRequestSize("512MB");
    return factory.createMultipartConfig();
    }

    @Bean
    public MultipartResolver multipartResolver() {
    org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(512000000);
    return multipartResolver;
    }

    이렇게 2개 Application.java 파일에 넣고, pom.xml
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
    </dependency>

    추가 하니 해결 되었네요.

    도움 주셔서 감사합니다. ^^
    2017.05.21 17:37
댓글쓰기 폼