쌩로그

스프링에서 AWS S3를 위한 파일업로드 코드 본문

Spring/Spring & Spring Boot

스프링에서 AWS S3를 위한 파일업로드 코드

.쌩수. 2023. 12. 7. 18:59
반응형

목록

  1. 포스팅 개요
  2. 본론
      2-1. AWS S3의 파일에 대한 정보를 얻는 클래스
      2-2. AWS S3 서비스 클래스
      2-3. AWS S3 Configuration 클래스
  3. 요약

1. 포스팅 개요

AWS S3를 이용해서 파일 업로드를 구현해야 하는 일이 있었고, 구글링과 Chat GPT를 통해 구현하여 사용한 코드들이다.
그 코드를 재사용하기 위해 기록하는 포스팅이다.

2. 본론

AWS S3의 파일 업로드를 위해 필요한 클래스들에 대한 예시 코드이다.

2-1. AWS S3의 파일에 대한 정보를 얻는 클래스

@Getter
public class FileInfo {
    UrlResource urlResource;    // S3 파일 Url
    String contentDisposition;  // HTTP 응답 헤더 중 하나로, 클라이언트가 서버에게 전송한 파일에 대한 정보

    @Builder
    public FileInfo(UrlResource urlResource, String contentDisposition) {
        this.urlResource = urlResource;
        this.contentDisposition = contentDisposition;
    }
}

2-2. AWS S3 서비스 클래스

@Slf4j
@Service
@RequiredArgsConstructor
public class S3Service {

    private final AmazonS3 amazonS3;

    @Value("${cloud.aws.s3.bucket}") // yml의 S3 Bucket 환경변수 정보
    private String bucket;

    ObjectMapper objectMapper = new ObjectMapper();

    // 업로드
    @Transactional
    public String saveFile(List<MultipartFile> multipartFiles) throws IOException {

        // AWS S3로 집어넣고, 파일이름과 Path를 map에 담는다.
        List<Map<String, String>> fileList = new ArrayList<>();

        for(MultipartFile file : multipartFiles) {
            // map
            Map<String, String> fileMap = new HashMap<>();

            // 파일에 대한 메타 데이터 처리
            ObjectMetadata objMeta = new ObjectMetadata();
            objMeta.setContentLength(file.getSize());
            objMeta.setContentType(file.getContentType());

            // S3에 밀어 넣기
            String originalFilename = file.getOriginalFilename(); // 파일 이름
            amazonS3.putObject(new PutObjectRequest(bucket, originalFilename, file.getInputStream(), objMeta));

            // 파일이름
            String name = originalFilename;

            // 확장자 얻기
            String type = originalFilename.substring(originalFilename.indexOf(".") + 1); // '.' 포함 X

            // src : 파일 url 소스
            String src = amazonS3.getUrl(bucket, originalFilename).toString();

            fileMap.put("name", name);
            fileMap.put("type", type);
            fileMap.put("src", src);

            fileList.add(fileMap);
        }
        log.info("파일 개수", fileList.size());
        log.info("파일 정보 = {}", fileList);

        // map을 JSON 형식으로 만들어서, String으로 변환 후에 던져준다.
        String result = objectMapper.writeValueAsString(fileList);

        return result;
    }

    // 파일 다운로드
    @Transactional
    public FileInfo downloadImage(String originalFilename) {
        if (!amazonS3.doesObjectExist(bucket, originalFilename)) { // 파일존재 확인한다.
            // 예외 처리
            // ...
        }
        UrlResource urlResource = new UrlResource(amazonS3.getUrl(bucket, originalFilename));
        String contentDisposition = "attachment; filename=\"" +  originalFilename + "\"";

        // HTTP header에 CONTENT_DISPOSITION 설정을 줌으로써 클릭 시 다운로드 진행될 수 있도록 한다.
        return new FileInfo(urlResource, contentDisposition);
    }


    // 삭제
    @Transactional
    public void deleteImage(String originalFilename) {
        if (!amazonS3.doesObjectExist(bucket, originalFilename)) { // 파일의 존재여부를 확인한다.
            // 예외 처리
            ...
        }
           amazonS3.deleteObject(new DeleteObjectRequest(bucket, originalFilename)); // 파일을 삭제한다.
        }

}

2-3. AWS S3 Configuration 클래스

@Configuration
public class S3Config {

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

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

    @Value("${cloud.aws.region.static}")          // AWS 리전 정보
    private String region;

    @Bean
    public AmazonS3Client amazonS3Client() {      // AmazonS3Client을 스프링 컨텍스트에 등록하는 메서드
        BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

        return (AmazonS3Client) AmazonS3ClientBuilder
                .standard()
                .withRegion(region)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .build();
    }

}

3. 요약

이상 AWS S3를 이용하여 파일 업로드를 백엔드에서 구현할 때 최소한으로 필요한 코드들이다.

728x90
Comments