SpringBoot & S3 (이미지)

최연재·2022년 7월 15일
0

기술 구현

목록 보기
3/3
  1. AWS 서비스에서 처리해야 하는 것들
  2. 로컬 환경에서 처리해야 하는 것들

1. AWS 서비스에서 처리해야 하는 것들

  1. S3 bucket 생성
  2. 퍼블릭 엑세스 설정
  3. 퍼블릭 정책 활성화
  1. 엑세스 키 생성
  • S3에 접근하려면 별도의 인증 과정이 필요한데, 이때 사용되는 것이 엑세스 키
  • 엑세스 키는 AWSAccessKeyId와 AWSSecretKey로 구성
  • 이거를 application.yml과 같은 파일에 입력해줘야함.(GitHub 이용할때, 이런 정보들 안 올리도록 조심!!! ./gitignore 이용!!!)

2. 로컬 환경에서 처리해야 하는 것들

1. gradle 설정

상황마다 달라서, 구글링해보기

2. S3Uploader.java 생성

@Slf4j
@RequiredArgsConstructor
@Component
public class S3Uploader {

    private final AmazonS3Client amazonS3Client;

    @Value("${cloud.aws.s3.bucket}")
    private String bucket;

    public String upload(MultipartFile multipartFile, String dirName) throws IOException {
        File uploadFile = convert(multipartFile)
                .orElseThrow(() -> new IllegalArgumentException("MultipartFile -> File로 전환이 실패했습니다."));

        return upload(uploadFile, dirName); // 밑으로 이동
    }

    private String upload(File uploadFile, String dirName) {
        String fileName = dirName + "/" + uploadFile.getName();
        String uploadImageUrl = putS3(uploadFile, fileName); // 여기에서 S3에 올리는듯 // 밑에 함수
        removeNewFile(uploadFile); // 맨 밑에 함수
        return uploadImageUrl;
    }

    private String putS3(File uploadFile, String fileName) { // 여기서 실제로 s3에 올라감
        amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(CannedAccessControlList.PublicRead));
        return amazonS3Client.getUrl(bucket, fileName).toString();
    }

    private void removeNewFile(File targetFile) { // 로컬에 저장한 정보를 이용해서 올렸다가, 로컬에 저장된거를 지우는거 같은데?
        if (targetFile.delete()) {
            log.info("파일이 삭제되었습니다."); //이게 제대로 실행 되는거
        } else {
            log.info("파일이 삭제되지 못했습니다.");
        }
    }

    private Optional<File> convert(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        File convertFile = new File(file.getOriginalFilename());
        //System.out.println(convertFile.createNewFile()); // 이미 있으면 false, 없으면 true
        if(convertFile.createNewFile()) { // 파일이 이전에 존재하지 않으면 true를 띄우고 들어감.
            try (FileOutputStream fos = new FileOutputStream(convertFile)) {
                fos.write(file.getBytes());
            }
            return Optional.of(convertFile);
        }
        return Optional.empty();
    }


}
  • S3Uploader.java \to S3에 정적 파일을 올리는 기능을 함
  • 동작 방식
    (1) MultipartFile을 전달 받음
    (2) convert를 통하여 MultipartFile을 File로 전환
    (3) 전환된 File을 S3에 'public 읽기' 권한으로 put
    (4) 로컬에 생성된 File 삭제(MultipartFile을 File로 전환하는 과정에서 로컬에 파일이 생성되었음)
    (5) 업로드된 파일의 S3 URL 주소를 반환
  • 위의 코드에서 'dirName'은 S3에 생성된 디렉토리

3. Controller

@PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam("data") MultipartFile multipartFile) throws IOException {
        return s3Uploader.upload(multipartFile, "static");
    }

받아온 multipartFile과 S3에 생성된 디렉토리의 이름(여기에서는 "static")을 입력

이 글은 향로님의 'SpringBoot & AWS S3 연동하기'를 통해 기능을 구현해보고 정리한 내용입니다.

profile
가보자고

0개의 댓글