반응형

Spring boot Rest API 파일 업로드 및 다운로드 예제 (1)입니다.

로컬에 파일을 업로드할 수 있도록 환경설정 및 VO, Service 단을 구현하겠습니다.


 

0. [Spring boot] REST API 기본 환경설정 및 CRUD 예제 참고 (1) ~ (6)

[SPRING BOOT] REST API 간단 예제 - (1) 프로젝트 생성

 

 

1. 환경

- Visual Studio Code : 1.61.2 version

- Spring boot : 2.5.7 version / gradle

- java 11

 

 

2. application.properties

# file upload
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.location=D:\\test\\spring boot\\test-springboot-3\\demo\\uploaded

- File upload 관련 설정을 application.properties에 추가했습니다.

- 파일이 저장될 경로는 프로젝트 내부로 설정했습니다.

 

 

3. FileVO.java

package com.test.demo.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter 
@Setter 
@ToString
public class FileVO {
  
  private int file_key;
  private String file_path;
  private String file_preview_path;
  private String file_name;
  private String original_name;
  private String file_type;
  
}

- FileVO 파일입니다.

- 파일 키 값, 파일 경로, 파일 미리보기 경로, 파일 이름, 원본 파일 이름, 파일 타입 값을 선언했습니다.

 

- 참고로 이 예제에서는 file_name을 새로 만들어서 저장하지 않았습니다.

- 파일 시스템을 더 정상적으로 이용하려면 오류가 나지 않을 새로운 파일명을 부여하는 것이 좋습니다.

 

 

4. FileService.java

package com.test.demo.service;

import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;
import java.util.stream.Stream;

public interface FileService {
  
  void init();
  void store(MultipartFile file);
  Stream<Path> loadAll();
  Path load(String filename);
  Resource loadAsResource(String filename);
  void deleteAll();
  void deleteFile(String filename);

}

- 구현할 서비스들을 인터페이스 안에 선언했습니다.

- 파일을 업로드, 다운로드, 미리보기, 삭제할 수 있는 서비스입니다.

 

 

5. FileServiceImpl.java

package com.test.demo.service;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;

import org.springframework.util.FileSystemUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
public class FileServiceImpl implements FileService {
  
  @Value("${spring.servlet.multipart.location}")
  private String uploadPath;

  @Override
  public void init() {
    try {
      Files.createDirectories(Paths.get(uploadPath));

    } catch (IOException e) {
      throw new RuntimeException("폴더 생성 실패");
    }
  }

  @Override
  public void store(MultipartFile file) {
    try {
      if (file.isEmpty()) {
        throw new Exception("빈 파일입니다.");
      }

      Path root = Paths.get(uploadPath);

      if (!Files.exists(root)) {
        init();
      }

      try (InputStream inputStream = file.getInputStream()) {
        Files.copy(inputStream, root.resolve(
            file.getOriginalFilename()), StandardCopyOption.REPLACE_EXISTING
        );
        
      } catch (Exception e) {
        throw new RuntimeException("파일을 저장할 수 없습니다. Error: " + e.getMessage());
      }

    } catch (Exception e) {
      throw new RuntimeException("파일을 저장할 수 없습니다. Error: " + e.getMessage());
    }
  }

  @Override
  public Stream<Path> loadAll() {
    try {
      Path root = Paths.get(uploadPath);
      return Files.walk(root, 1).filter(path -> !path.equals(root));
      
    } catch (IOException e) {
      throw new RuntimeException("파일 읽기 실패", e);
    }
  }

  @Override
  public Path load(String filename) {
    return Paths.get(uploadPath).resolve(filename);
  }

  @Override
  public Resource loadAsResource(String filename) {
    try {
      Path file = load(filename);
      Resource resource = new UrlResource(file.toUri());
      
      if (resource.exists() || resource.isReadable()) {
        return resource;

      } else {
        throw new RuntimeException("파일을 읽을 수 없습니다. : " + filename);
      }

    } catch (MalformedURLException e) {
      throw new RuntimeException("파일을 읽을 수 없습니다. : " + filename, e);
    }
  }

  @Override
  public void deleteAll() {
    FileSystemUtils.deleteRecursively(Paths.get(uploadPath).toFile());
  }

  @Override
  public void deleteFile(String filename) {
    FileSystemUtils.deleteRecursively(Paths.get(uploadPath + "\\" + filename).toFile());
  }

}

- 위의 FileService를 implements 하여 FileServiceImpl 파일을 추가했습니다.

- application.properties에 선언한 파일 경로를 @Value를 통해 가져옵니다.

 

- init : 폴더가 없으면 폴더를 생성합니다.

- store : 파일이 비어있는지 확인하고, 파일을 저장합니다.

- loadAll : 모든 파일의 정보 목록을 가져옵니다.

- load : 선택된 파일 정보를 가져옵니다.

- deleteAll : 모든 파일이 들어있는 폴더를 삭제합니다.

- deleteFile : 파일을 삭제합니다.

 

 

6. 다음 글 참고

- [SPRING BOOT] REST API File 예제 - (2) Controller, Swagger UI

 

 

 

이상으로 Spring boot Rest API 파일 업로드 예제 중 환경설정, VO 및 Service를 구현해보았습니다.


 

반응형