Object Manage

최신 업데이트:2025-08-27 10:06:22

WOS Java SDK는 객체 관리에 필요한 다양한 인터페이스를 제공합니다. 본 문서에서는 이러한 인터페이스를 활용하여 객체를 관리하는 일반적인 작업 방법을 소개합니다.

1. 오브젝트 메타데이터 설정

WosClient.setObjectMetadata를 사용하여 오브젝트 메타데이터(사용자 정의 메타데이터 포함)를 설정할 수 있습니다. 아래 예시는 오브젝트 메타데이터를 설정하는 방법을 보여줍니다.

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// WosClient 인스턴스 생성
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

SetObjectMetadataRequest request = new SetObjectMetadataRequest("bucketname", "objectname");
request.addUserMetadata("property1", "property-value1");
// 사용자 정의 메타데이터 설정
ObjectMetadata metadata = wosClient.setObjectMetadata(request);

System.out.println("\t" + metadata.getUserMetadata("property1"));

2. 오브젝트 메타데이터 조회

WosClient.getObjectMetadata를 사용하여 오브젝트 크기, MIME 타입, 사용자 정의 메타데이터 등 오브젝트 메타데이터를 조회할 수 있습니다. 아래 예시는 오브젝트 메타데이터를 조회하는 방법을 보여줍니다.

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// WosClient 인스턴스 생성
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ObjectMetadata metadata = wosClient.getObjectMetadata("bucketname", "objectname");
System.out.println("\t" + metadata.getContentType());
System.out.println("\t" + metadata.getContentLength());
System.out.println("\t" + metadata.getUserMetadata("property"));

3. 오브젝트 ACL 조회

WosClient.getObjectAcl을 통해 오브젝트의 ACL(Access Control List)을 조회할 수 있습니다. 아래 예시는 오브젝트 ACL을 조회하는 방법을 보여줍니다.

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// WosClient 인스턴스 생성
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

AccessControlList acl = wosClient.getObjectAcl("bucketname", "objectname");
System.out.println(acl);

4. 오브젝트 목록 조회

WosClient.listObjects를 사용하여 버킷 내 오브젝트 목록을 조회할 수 있습니다.

설정 가능한 파라미터

파라미터 설명 Java SDK 메서드
bucketName 버킷 이름 ListObjectsRequest.setBucketName
prefix 지정한 접두사로 시작하는 오브젝트만 반환 ListObjectsRequest.setPrefix
marker 리스트 시작 위치로, 마커 이후 사전순 첫 오브젝트부터 반환 ListObjectsRequest.setMarker
maxKeys 한 번에 반환할 최대 오브젝트 개수(1~1000, 1000 초과 시 무조건 1000) ListObjectsRequest.setMaxKeys
delimiter 오브젝트 이름 그룹화 문자. 해당 문자가 포함된 공통접두사 반환 ListObjectsRequest.setDelimiter

단순 목록 조회

아래 예시는 최대 1,000개의 오브젝트를 한 번에 조회합니다.

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// WosClient 인스턴스 생성
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ObjectListing result = wosClient.listObjects("bucketname");
for (WosObject wosObject : result.getObjects()) {
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

참고:

  • 한 번 호출 시 최대 1,000개 오브젝트 반환. 1,000개 초과 시 ObjectListing.isTruncated가 true이며, 이후 조회는 ObjectListing.getNextMarker를 사용.
  • 모든 오브젝트를 조회하려면 반복(페이징) 조회를 사용해야 합니다.

지정 개수만큼 오브젝트 조회

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);
ObjectListing result = wosClient.listObjects(request);
for (WosObject wosObject : result.getObjects()) {
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

접두사로 오브젝트 조회

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);
request.setPrefix("prefix");
ObjectListing result = wosClient.listObjects(request);
for (WosObject wosObject : result.getObjects()) {
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

마커로 오브젝트 조회

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);
request.setMarker("test");
ObjectListing result = wosClient.listObjects(request);
for (WosObject wosObject : result.getObjects()) {
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

오브젝트 전체 페이징 조회

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);

ObjectListing result;
do {
    result = wosClient.listObjects(request);
    for (WosObject wosObject : result.getObjects()) {
        System.out.println("\t" + wosObject.getObjectKey());
        System.out.println("\t" + wosObject.getOwner());
    }
    request.setMarker(result.getNextMarker());
} while (result.isTruncated());

“폴더” 내 모든 오브젝트 조회

WOS는 폴더를 별도로 지원하지 않으며 모든 오브젝트가 버킷 내에 직접 저장됩니다. 폴더는 key가 /로 끝나는 0바이트 오브젝트로써 논리적으로 구분됩니다. 특정 폴더의 오브젝트만 조회하려면 prefix 값을 폴더명으로 지정하면 됩니다.

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setPrefix("dir/");
request.setMaxKeys(1000);

ObjectListing result;
do {
    result = wosClient.listObjects(request);
    for (WosObject wosObject : result.getObjects()) {
        System.out.println("\t" + wosObject.getObjectKey());
        System.out.println("\t" + wosObject.getOwner());
    }
    request.setMarker(result.getNextMarker());
} while (result.isTruncated());

폴더 단위(디렉토리별 그룹) 오브젝트 목록 조회

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(1000);
// delimiter를 "/"로 설정
request.setDelimiter("/");
ObjectListing result = wosClient.listObjects(request);
System.out.println("루트 디렉터리 내 오브젝트:");
for (WosObject wosObject : result.getObjects()) {
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}
listObjectsByPrefix(wosClient, request, result);

static void listObjectsByPrefix(WosClient wosClient, ListObjectsRequest request, ObjectListing result) throws WosException {
    for (String prefix : result.getCommonPrefixes()) {
        System.out.println("폴더 [" + prefix + "] 내 오브젝트:");
        request.setPrefix(prefix);
        result = wosClient.listObjects(request);
        for (WosObject wosObject : result.getObjects()) {
            System.out.println("\t" + wosObject.getObjectKey());
            System.out.println("\t" + wosObject.getOwner());
        }
        listObjectsByPrefix(wosClient, request, result);
    }
}

참고:

  • 위 코드에서는 단일 폴더 내부에 1,000개가 넘는 오브젝트가 있는 경우 처리가 되지 않습니다.
  • 모든 하위 폴더까지 재귀적으로 조회하며, 폴더 key가 항상 "/"로 끝남을 전제로, delimiter는 재귀적으로 호출 시 항상 "/"로 유지해야 합니다.
  • 각 단계에서 ObjectListing.getObjects는 해당 "폴더"의 오브젝트, ObjectListing.getCommonPrefixes는 하위 폴더의 프리픽스를 반환합니다.

5. 오브젝트 삭제

단일 오브젝트 삭제

WosClient.deleteObject로 단일 오브젝트를 삭제할 수 있습니다.

WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);
wosClient.deleteObject("bucketname", "objectname");

다중(일괄) 오브젝트 삭제

WosClient.deleteObjects를 사용해 한 번에 최대 1,000개 오브젝트를 일괄 삭제할 수 있습니다.

WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest("bucketname");
wosClient.deleteObjects(deleteRequest);

6. 오브젝트 복사

오브젝트 복사는 WOS 내에 오브젝트 사본을 생성하는 작업입니다.

WosClient.copyObject를 사용하여 오브젝트를 복사할 수 있습니다. 복사 시 메타데이터 및 권한을 새로 지정할 수 있으며, 조건부 복사도 지원합니다.

제한사항

  • 소스 오브젝트에 대한 읽기 권한이 필요합니다.
  • 리전(region) 간 복사는 지원하지 않습니다.
  • 소스 오브젝트 크기는 5GB 이하여야 합니다.(1GB 미만 파일은 단순 복사를 권장, 대용량은 멀티파트 복사)
  • 아카이브 클래스 오브젝트는 복사 전 반드시 복원이 필요합니다.

단순 복사

WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

try {
    CopyObjectResult result = wosClient.copyObject("sourcebucketname", "sourceobjectname", "destbucketname", "destobjectname");
    System.out.println("\t" + result.getStatusCode());
    System.out.println("\t" + result.getEtag());
} catch (WosException e) {
    // 복사 실패 시
    System.out.println("HTTP Code: " + e.getResponseCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Error Message: " + e.getErrorMessage());
    System.out.println("Request ID: " + e.getErrorRequestId());
    System.out.println("Host ID: " + e.getErrorHostId());
}

복사 시 오브젝트 메타데이터 덮어쓰기

WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

CopyObjectRequest request = new CopyObjectRequest("sourcebucketname", "sourceobjectname", "destbucketname", "destobjectname");
// 메타데이터 덮어쓰기 활성화
request.setReplaceMetadata(true);
ObjectMetadata newObjectMetadata = new ObjectMetadata();
newObjectMetadata.setContentType("image/jpeg");
newObjectMetadata.addUserMetadata("property", "property-value");
newObjectMetadata.setObjectStorageClass(StorageClassEnum.WARM);
request.setNewObjectMetadata(newObjectMetadata);
CopyObjectResult result = wosClient.copyObject(request);
System.out.println("\t" + result.getEtag());

참고:

  • CopyObjectRequest.setReplaceMetadata(true).setNewObjectMetadata를 함께 사용해야 합니다.

조건부 복사

조건을 하나 이상 지정할 수 있으며, 모든 조건을 충족해야 복사 작업이 수행됩니다.

파라미터 설명 Java SDK 메서드
Copy-Source-If-Modified-Since 소스 오브젝트가 지정한 시간보다 늦게 수정된 경우에만 복사. 만족하지 않으면 예외 CopyObjectRequest.setIfModifiedSince
Copy-Source-If-Unmodified-Since 소스 오브젝트가 지정한 시간 이후 수정되지 않은 경우만 복사. 만족하지 않으면 예외 CopyObjectRequest.setIfUnmodifiedSince
Copy-Source-If-Match 소스 오브젝트의 ETag가 값과 일치할 때만 복사. 만족하지 않으면 예외 CopyObjectRequest.setIfMatchTag
Copy-Source-If-None-Match 소스 오브젝트의 ETag가 값과 다를 때만 복사. 만족하지 않으면 예외 CopyObjectRequest.setIfNoneMatchTag

참고:

  • 소스 오브젝트의 ETag는 오브젝트의 MD5 값입니다.
  • 복사 조건이 맞지 않으면 HTTP 412 Precondition Failed가 반환됩니다.
  • Copy-Source-If-Modified-Since와 Copy-Source-If-None-Match는 함께 사용할 수 있고, Copy-Source-If-Unmodified-Since와 Copy-Source-If-Match도 함께 사용할 수 있습니다.

예시

WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

CopyObjectRequest request = new CopyObjectRequest("sourcebucketname", "sourceobjectname", "destbucketname", "destobjectname");

request.setIfModifiedSince(new SimpleDateFormat("yyyy-MM-dd").parse("2016-01-01"));
request.setIfNoneMatchTag("none-match-etag");

CopyObjectResult result = wosClient.copyObject(request);
System.out.println("\t" + result.getEtag());

멀티파트 복사

멀티파트 복사는 멀티파트 업로드의 특수 형태로, 기존 오브젝트의 일부를 복사하여 각 파트를 업로드(조립)하는 방식입니다. 대용량 오브젝트 복사 시 WosClient.copyPart를 사용합니다. 아래는 멀티파트 복사 예시입니다.

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

final String destBucketName = "destbucketname";
final String destObjectKey = "destobjectname";
final String sourceBucketName = "sourcebucketname";
final String sourceObjectKey = "sourceobjectname";

// WosClient 인스턴스 생성
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

// 스레드 풀 초기화
ExecutorService executorService = Executors.newFixedThreadPool(20);

// 멀티파트 업로드 초기화
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(destBucketName, destObjectKey);
InitiateMultipartUploadResult result = wosClient.initiateMultipartUpload(request);

final String uploadId = result.getUploadId();
System.out.println("\t" + uploadId + "\n");

// 소스 오브젝트 정보 조회
ObjectMetadata metadata = wosClient.getObjectMetadata(sourceBucketName, sourceObjectKey);
// 파트 당 100MB 복사
long partSize = 100 * 1024 * 1024L;
long objectSize = metadata.getContentLength();

// 파트 개수 계산
long partCount = objectSize % partSize == 0 ? objectSize / partSize : objectSize / partSize + 1;

final List<PartEtag> partEtags = Collections.synchronizedList(new ArrayList<PartEtag>());

// 병렬로 각 파트 복사
for (int i = 0; i < partCount; i++) {
    // 각 파트의 바이트 범위
    final long rangeStart = i * partSize;
    final long rangeEnd = (i + 1 == partCount) ? objectSize - 1 : rangeStart + partSize - 1;
    final int partNumber = i + 1;
    executorService.execute(new Runnable() {
        @Override
        public void run() {
            CopyPartRequest request = new CopyPartRequest();
            request.setUploadId(uploadId);
            request.setSourceBucketName(sourceBucketName);
            request.setSourceObjectKey(sourceObjectKey);
            request.setDestinationBucketName(destBucketName);
            request.setDestinationObjectKey(destObjectKey);
            request.setByteRangeStart(rangeStart);
            request.setByteRangeEnd(rangeEnd);
            request.setPartNumber(partNumber);
            CopyPartResult result;
            try {
                result = wosClient.copyPart(request);
                System.out.println("Part#" + partNumber + " done\n");
                partEtags.add(new PartEtag(result.getEtag(), result.getPartNumber()));
            } catch (WosException e) {
                e.printStackTrace();
            }
        }
    });
}

// 완료 대기
executorService.shutdown();
while (!executorService.isTerminated()) {
    try {
        executorService.awaitTermination(5, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

// 멀티파트 업로드 완료
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(destBucketName, destObjectKey, uploadId, partEtags);
wosClient.completeMultipartUpload(completeMultipartUploadRequest);
이 문서의 내용이 도움이 되었습니까?
아니오
정상적으로 제출되었습니다.피드백을 주셔서 감사합니다.앞으로도 개선을 위해 노력하겠습니다.