HeadObject로 S3 객체 존재 여부 확인하기 (SDK 2)

2025. 9. 30. 14:46·SPRING/HOW-TO

🍒배경

AWS S3는 객체를 고유한 키(Key) 값으로 관리하는 스토리지 서비스입니다. 개발을 하다보면 특정 버킷 안에 지정된 키 값을 가진 객체가 실제로 존재하는지 확인해야 하는 경우가 발생합니다. 예를 들어, 업로드가 정상적으로 완료되었는지 검증하거나 다운로드 전에 객체 존재 여부를 확인하는 경우 등이 있습니다. 

 

이는 HeadObject를 사용하여 쉽게 확인할 수 있습니다. 객체의 실제 데이터를 가져오지 않고 해당 객체의 메타데이터(크기, 수정 시각, ETag 등)만 반환하기 때문에 가볍게 존재 여부를 확인할 수 있습니다.

 

🍒사전 준비

🌱의존성 주입

implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.1")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3'

 

🌱S3Config

package com.alphano.alphano.common.config;

import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;

@Configuration
@RequiredArgsConstructor
@Slf4j
public class S3Config {

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

    private S3Client s3Client;
    private S3Presigner s3Presigner;

    @Bean
    public S3Client amazonS3() {
        this.s3Client = S3Client.builder()
                .region(Region.of(awsRegion))
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();
        return this.s3Client;
    }

    @Bean
    public S3Presigner amazonS3Presigner() {
        this.s3Presigner = S3Presigner.builder()
                .region(Region.of(awsRegion))
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();
        return this.s3Presigner;
    }

    @PreDestroy
    public void shutdown() {
        try {
            if (s3Presigner != null) s3Presigner.close();
            if (s3Client != null) s3Client.close();
            log.info("S3 SDK 자원 정상 해제 완료");
        } catch (Exception e) {
            log.warn("S3 SDK 자원 해제 실패", e);
        }
    }
}

 

🍒코드 작성

공식문서를 참고하여 작성하였습니다. 

 

아래는 공식문서의 코드입니다. 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;

import java.nio.file.Path;

import static com.example.s3.util.S3DirectoryBucketUtils.createDirectoryBucket;
import static com.example.s3.util.S3DirectoryBucketUtils.createS3Client;
import static com.example.s3.util.S3DirectoryBucketUtils.deleteAllObjectsInDirectoryBucket;
import static com.example.s3.util.S3DirectoryBucketUtils.deleteDirectoryBucket;
import static com.example.s3.util.S3DirectoryBucketUtils.getFilePath;
import static com.example.s3.util.S3DirectoryBucketUtils.putDirectoryBucketObject;

    /**
     * Retrieves metadata for an object in the specified S3 directory bucket.
     *
     * @param s3Client   The S3 client used to interact with S3
     * @param bucketName The name of the directory bucket
     * @param objectKey  The key (name) of the object to retrieve metadata for
     * @return True if the object exists, false otherwise
     */
    public static boolean headDirectoryBucketObject(S3Client s3Client, String bucketName, String objectKey) {
        logger.info("Retrieving metadata for object: {} from bucket: {}", objectKey, bucketName);

        try {
            // Create a HeadObjectRequest
            HeadObjectRequest headObjectRequest = HeadObjectRequest.builder()
                    .bucket(bucketName)
                    .key(objectKey)
                    .build();

            // Retrieve the object metadata
            HeadObjectResponse response = s3Client.headObject(headObjectRequest);
            logger.info("Amazon S3 object: \"{}\" found in bucket: \"{}\" with ETag: \"{}\"", objectKey, bucketName,
                    response.eTag());
            logger.info("Content-Type: {}", response.contentType());
            logger.info("Content-Length: {}", response.contentLength());
            logger.info("Last Modified: {}", response.lastModified());
            return true;

        } catch (S3Exception e) {
            logger.error("Failed to retrieve object metadata: {} - Error code: {}", e.awsErrorDetails().errorMessage(),
                    e.awsErrorDetails().errorCode(), e);
            return false;
        }
    }

해당 코드는 디렉터리 버킷에 objectKey를 가진 객체가 존재할 경우, 객체의 메타데이터를 로그로 출력한 다음 true 반환합니다. 객체가 존재하지 않는다면 S3Exception이 발생하고 false를 반환합니다. 

  • `HeadObjectRequest` : Amazon S3와 같은 서비스에서 객체의 메타데이터(예: 크기, 마지막 수정 날짜, ETag)를 가져오기 위해 사용되는 요청 객체
  • `HeadObjectResponse` : Amazon S3와 같은 서비스에서 HeadObjectRequest를 실행한 결과로 반환되는 응답 객체. 해당 객체의 메타데이터와 HTTP 헤더 정보를 담고 있음.

메타데이터는 필요하지 않고 지정된 키 값을 가진 객체가 존재하는지 확인하는 것이기 때문에 코드를 리팩토링하겠습니다. 

 

🌟최종 코드

@Service
@RequiredArgsConstructor
public class S3Service {
    private final S3Client s3Client;

    public boolean objectExists(String bucketName, String objectKey) {
        try {
            HeadObjectRequest headObjectRequest = HeadObjectRequest.builder()
                    .bucket(bucketName)
                    .key(objectKey)
                    .build();
            s3Client.headObject(headObjectRequest);
            return true;
        } catch (S3Exception e) {
            return false;
        }
    }
}
  1. 메서드명을 직관적으로 변경했습니다.
  2. 기존에 인자로 전달받던 `s3Client`는 의존성 주입 방식으로 변경했습니다. 
  3. 메타데이터가 필요하지 않으므로 `HeadObjectResponse` 객체를 별도로 받지 않고 단순히 호출만 수행하도록 수정했습니다.

관련 글:

2025.06.15 - [SPRING/HOW-TO] - Presigned URL로 S3 프라이빗 버킷 이미지 조회하기 (SDK v2)

2025.06.22 - [SPRING/HOW-TO] - Presigned URL로 S3 이미지 업로드 및 삭제 기능 구현하기 (SDK 2)

'SPRING > HOW-TO' 카테고리의 다른 글

Presigned URL로 S3 이미지 업로드 및 삭제 기능 구현하기 (SDK 2)  (5) 2025.06.22
SSH 터널링으로 프라이빗 RDS에 MySQL Workbench 연결하기  (3) 2025.06.18
Presigned URL로 S3 프라이빗 버킷 이미지 조회하기 (SDK v2)  (2) 2025.06.15
'SPRING/HOW-TO' 카테고리의 다른 글
  • Presigned URL로 S3 이미지 업로드 및 삭제 기능 구현하기 (SDK 2)
  • SSH 터널링으로 프라이빗 RDS에 MySQL Workbench 연결하기
  • Presigned URL로 S3 프라이빗 버킷 이미지 조회하기 (SDK v2)
seo-cherry
seo-cherry
devyeonee911 님의 블로그 입니다.
  • seo-cherry
    Emergency
    seo-cherry
  • 전체
    오늘
    어제
    • 분류 전체보기 (11)
      • SPRING (7)
        • TIL (3)
        • HOW-TO (4)
      • CI-CD (1)
      • REVIEW (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
seo-cherry
HeadObject로 S3 객체 존재 여부 확인하기 (SDK 2)
상단으로

티스토리툴바