페이지

2021년 9월 7일 화요일

Maven + Spring 파일 업로드 기초

Maven + Spring 파일 업로드 기초

사용 환경

  • Windows 10
  • Java 1.8
  • Maven 3.8.2
  • Spring 5.0.6

Hello 프로젝트 따라하기

  1. 프로젝트 생성

    브라우져에서 spring initializr를 방문하여 아래와 같이 입력하고 GENERATE 버튼을 클릭합니다.

    • Project: Maven Project
    • Language: Java
    • Spring Boot: 2.5.4
    • Project Meta:
      • Group: trvoid
      • Artifact: file-upload
      • Name: File Upload
      • Package name: trvoid.fileupload
      • Packaging: Jar
      • Java: 8
    • Dependencies: Spring Web

    생성된 프로젝트 파일을 다운로드하여 압축을 풉니다. 프로젝트 폴더 구조는 아래와 같습니다.

    hello
      |-src
        |-main
          |-java
            |-trvoid.fileupload
              |-FileUploadApplication.java
        |-test
          |-java
            |-trvoid.fileupload
              |-FileUploadApplicationTests.java
      |-pom.xml
    

    pom.xml 파일에서 의존성 항목과 빌드 플러그인을 확인할 수 있습니다.

    <dependencies>
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-maven-plugin</artifactId>  
            </plugin>
        </plugins>
    </build>
    

    FileUploadApplication.java 파일의 내용은 아래와 같습니다.

    package trvoid.fileupload;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class FileUploadApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(FileUploadApplication.class, args);
        }
    
    }
    
  2. 파일 저장소 서비스 추가

    src/trvoid/fileupload/storage/StorageService.java

    package trvoid.fileupload.storage;
    
    import org.springframework.web.multipart.MultipartFile;
    
    public interface StorageService {
        void init();
        public void deleteAll()
        void store(MultipartFile file);
    }
    

    src/trvoid/fileupload/storage/FileSystemStorageService.java

    package trvoid.fileupload.storage;
    
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    @Service
    public class FileSystemStorageService implements StorageService {
        private final Path rootLocation;
    
        public FileSystemStorageService() {
            this.rootLocation = Paths.get("upload-dir");
        }
    
        @Override
        public void init() {
            try {
                Files.createDirectory(rootLocation);
            } catch (IOException e) {
                throw new RuntimeException("Could not initialize storage", e);
            }
        }
    	
    	@Override  
        public void deleteAll() {  
            FileSystemUtils.deleteRecursively(rootLocation.toFile());  
        }
    
        @Override
        public void store(MultipartFile file) {
            try {
                if (file.isEmpty()) {
                    throw new RuntimeException("Failed to store empty file " + file.getOriginalFilename());
                }
                Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename()));
            } catch (IOException e) {
                throw new RuntimeException("Failed to store file " + file.getOriginalFilename(), e);
            }
        }
    }
    
  3. 컨트롤러 추가

    src/trvoid/fileupload/FileUploadController.java

    package trvoid.fileupload;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    import trvoid.fileupload.storage.StorageService;
    
    @RestController
    public class FileUploadController {
        private final StorageService storageService;
    
        @Autowired
        public FileUploadController(StorageService storageService) {
            this.storageService = storageService;
        }
    
        @PostMapping("/file/upload")
        public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                       @RequestParam("fileUsage") String fileUsage) {
            storageService.store(file);
            
            System.out.println(String.format("File Usage: %s", fileUsage));
    
            return "success";
        }
    }
    
  4. 업로드 파일 크기와 요청 크기 제한

    src/main/resources/application.properties

    spring.servlet.multipart.max-file-size=128KB  
    spring.servlet.multipart.max-request-size=128KB
    
  5. 파일 저장소 초기화를 위해 CommandLineRunner 추가

    src/trvoid/fileupload/FileUploadApplication.java

    package trvoid.fileupload;
    
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import trvoid.fileupload.storage.StorageService;
    
    @SpringBootApplication
    public class FileUploadApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(FileUploadApplication.class, args);
        }
    
        @Bean
        CommandLineRunner init(StorageService storageService) {
            return (args) -> {
                storageService.deleteAll();
                storageService.init();
            };
        }
    }
    
  6. 컴파일

    >mvn compile
    
  7. 실행

    >mvn spring-boot:run
    
  8. 파일 업로드 요청

    HTTP 클라이언트 프로그램(Insomnia, Postman, cURL 등)에서 아래와 같이 지정하여 파일 업로드 요청

    요청이 정상적으로 처리되었다면 아래와 같은 응답이 표시될 것입니다.

    success
    

    현재 폴더 아래에 upload-dir이 생성되었고 그 아래에서 업로드 파일이 존재하는지 확인합니다. 그리고 서버 실행 터미널에 File Usage: xxx와 같은 문자열이 표시되는지 확인합니다.

Written with StackEdit.

댓글 없음:

댓글 쓰기

가설 검정 제대로 이해하기

가설 검정 제대로 이해하기 ( 주의 : 공부하면서 작성하는 문서라서 오류가 있을 수 있습니다.) 1. 문제 정의 1.1. 사례 기존 가설: 20 대 한국인 남성의 100 미터 달리기 평균 속도는 17 초 ...