본문 바로가기
개발/AWS

[AWS] AWS + S3 + Spring boot File 업로드

by 설이주인 2023. 8. 7.

AWS - 버킷은 이미 생성 완료로 진행합니다. 필요하시다면 아래 링크를 확인해주세요

 

1. build.gradle 추가

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation 'com.amazonaws:aws-java-sdk-s3'
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')

2. application.yml 정보 추가

3. S3 Config

@Slf4j
//설정파일 선언
@Configuration
public class S3Config {

  @Value("${cloud.aws.credentials.access-key}")
  private String accessKey;

  @Value("${cloud.aws.credentials.secret-key}")
  private String secretKey;

  @Value("${cloud.aws.region.static}")
  private String region;

	//외부 Bean선언, 싱글톤 선언
  @Bean
  public AmazonS3Client amazonS3Client() {
    BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
    return (AmazonS3Client) AmazonS3ClientBuilder.standard()
        .withRegion(region)
        .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
        .build();
  }
}

 

4. 파일 request 생성

@Data
@AllArgsConstructor
public class BoardPostRequest {

  @NotEmpty
  private String title;
  private String content;

  /**
   * AttachPostRequest
   * 파일 확장자, 파일 이름, 파일 사이즈는 service단 안에서 추출 가능
   * */
  private List<MultipartFile> files; //파일
}

 

5. file util 생성

@Slf4j
@Component
@RequiredArgsConstructor
public class FileUtil {

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

	//s3클라이언트가 있지만 그건 버전 1
	//AmazonS3Client 버전2 최신꺼 쓰자
  private final AmazonS3Client amazonS3Client;

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

  private String upload(File file, String dirName) {
    String fileName = dirName + "/" + file.getName();
    String uploadFileUrl = putS3(file, fileName);

		// convert()함수로 인해서 로컬에 생성된 File 삭제 
		// (MultipartFile -> File 전환 하며 로컬에 파일 생성됨)
    deleteFile(file);
    
		// 업로드된 파일의 S3 URL 주소 반환
    return uploadFileUrl;
  }

	//s3 저장 ,return uploadFileUrl
  private String putS3(File file, String fileName) {
		//s3저장
    amazonS3Client.putObject(
        new PutObjectRequest(bucket, fileName, file).withCannedAcl(CannedAccessControlList.PublicRead)  //PublicRead
    );
    return amazonS3Client.getUrl(bucket, fileName).toString();
  }

	//임시로 생성하는 파일 삭제
  private void deleteFile(File targetFile) {
    if (targetFile.delete()) {
      log.info("삭제 성공");
    } else log.info("삭제 실패");
  }

  //MultipartFile to File
  private Optional<File> convert(MultipartFile file) throws IOException {
    File convertFile = new File(file.getOriginalFilename());  //upload파일 이름
    if (convertFile.createNewFile()) {
      try (FileOutputStream stream = new FileOutputStream(convertFile)) {
        stream.write(file.getBytes());
      }
      return Optional.of(convertFile);
    }
    return Optional.empty();
  }

}

 

6. Controller + Service

 

+) postman으로 진행시 파일 업로드 참고

https://galid1.tistory.com/754

 

Spring Boot - 개발자를 기억하게하지 말자 (파일리스트와 데이터리스트 요청을 하나의 객체로 바인

file과 data를 객체로 바인딩하기 Spring을 이용해 Rest API 개발중, file과 data를 같이 업로드해야 하는 상황이 있었습니다. file과 data는 논리적으로 연관관계가 있었으

galid1.tistory.com

 


 

참고 링크

https://jojoldu.tistory.com/300

 

SpringBoot & AWS S3 연동하기

안녕하세요? 이번 시간엔 SpringBoot & AWS S3 연동하기 예제를 진행해보려고 합니다. 모든 코드는 Github에 있기 때문에 함께 보시면 더 이해하기 쉬우실 것 같습니다. (공부한 내용을 정리하는 Github와

jojoldu.tistory.com