기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
버전 1과 버전 2 간의 S3 클라이언트 차이점 AWS SDK for Java
이 주제에서는 Java용 SDK 버전 1과 버전 2의 S3 클라이언트 간 차이점이 마이그레이션 도구가 마이그레이션을 자동화하는 방법에 따라 구성됩니다. 이 도구는 대부분의 메서드를 V1에서 V2로 마이그레이션하도록 지원하지만 일부 메서드는 수동 마이그레이션이 필요합니다. S3 클라이언트 메서드 외에도 일부 S3 V1 클래스에는 수동으로 마이그레이션해야 하는 직접 V2와 동등한 V2가 없습니다.
목차
마이그레이션 도구에서 지원하는 V1 메서드 예제
마이그레이션 도구는 대부분의 메서드를 V1에서 V2로 자동으로 마이그레이션합니다. putObject
및 getObject
메서드는 두 가지 예입니다.
putObject
// SDK V1 s3Client.putObject("my-bucket", "my-key", "Hello World!"); // SDK V2 s3Client.putObject(req -> req .bucket("my-bucket") .key("my-key"), RequestBody.fromString("Hello World!"));
getObject
// SDK V1 S3Object object = s3Client.getObject("my-bucket", "my-key"); InputStream content = object.getObjectContent(); // SDK V2 ResponseInputStream<GetObjectResponse> response = s3Client.getObject(req -> req .bucket("my-bucket") .key("my-key"));
수동 마이그레이션이 필요한 V1 메서드
다음 V1 S3 클라이언트 메서드를 수동으로 마이그레이션해야 합니다. 마이그레이션 도구를 사용하면 V2 출력 Java 파일에이 주제로 연결되는 설명이 표시됩니다.
V1에서 V2S3ObjectId
로 V1 getObject
사용 V2 GetObjectRequest.builder()
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); S3ObjectId s3ObjectId = new S3ObjectId( "my-bucket", "object-key", "abc123version" ); GetObjectRequest getRequest= new GetObjectRequest(s3ObjectId); S3Object s3ObjectVersioned = s3Client.getObject(getRequest); // SDK V2 // V2 does not include a 'S3ObjectId' class. V2 uses the request builder pattern // to supply the bucket, key, and version parameters. S3Client s3Client = S3Client.builder() .region(Region.US_WEST_2) .build(); GetObjectRequest getRequest = GetObjectRequest.builder() .bucket("my-bucket") .key("object-key") .versionId("abc123version") .build(); ResponseInputStream<GetObjectResponse> response = s3Client.getObject(getRequest);
V1에서 V2listNextBatchOfObjects
로 listObjectsV2Paginator
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); ObjectListing objectListing = s3ClientV1.listObjects("bucket-name"); while (objectListing.isTruncated()) { objectListing = s3ClientV1.listNextBatchOfObjects(objectListing); for (S3ObjectSummary summary : objectListing.getObjectSummaries()) { System.out.println(summary.getKey()); } } // SDK V2 S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); ListObjectsV2Request request = ListObjectsV2Request.builder() .bucket("bucket-name") .build(); // V2 returns a paginator. ListObjectsV2Iterable responses = s3Client.listObjectsV2Paginator(request); for (ListObjectsV2Response page : responses) { page.contents().forEach(content -> { System.out.println(content.key()); }); }
V1에서 V2listNextBatchOfVersions
로 listObjectVersionsPaginator
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); VersionListing versionListing = s3ClientV1.listVersions("bucket-name", "prefix"); while (versionListing.isTruncated()) { versionListing = s3ClientV1.listNextBatchOfVersions(versionListing); for (S3VersionSummary version : versionListing.getVersionSummaries()) { System.out.println(version.getKey() + " " + version.getVersionId()); } } // SDK V2 S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); ListObjectVersionsRequest request = ListObjectVersionsRequest.builder() .bucket("bucket-name") .prefix("prefix") .build(); // V2 returns a paginator. ListObjectVersionsIterable responses = s3ClientV2.listObjectVersionsPaginator(request); for (ListObjectVersionsResponse page : responses) { page.versions().forEach(version -> { System.out.println(version.key() + " " + version.versionId()); }); }
selectObjectContent
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); SelectObjectContentRequest request = new SelectObjectContentRequest() .withBucket("bucket-name") .withKey("object-key") .withExpression("select * from S3Object") .withExpressionType(ExpressionType.SQL) SelectObjectContentResult result = s3ClientV1.selectObjectContent(request); InputStream resultInputStream = result.getPayload().getRecordsInputStream(); // SDK V2 // In V2, 'selectObjectContent()' is available only on the S3AsyncClient. // V2 handles responses using an event-based 'SelectObjectContentEventStream'. S3AsyncClient s3ClientV2 = S3AsyncClient.builder() .region(Region.US_WEST_2) .build(); SelectObjectContentRequest request = SelectObjectContentRequest.builder() .bucket("bucket-name") .key("object-key") .expression("select * from S3Object") .expressionType(ExpressionType.SQL) .build(); SelectObjectContentResponseHandler handler = new SelectObjectContentResponseHandler() { // Implement the required abstract methods such as 'onEventStream()'. }; CompletableFuture<Void> future = s3ClientV2.selectObjectContent(request, handler); // The 'SelectObjectContentResponseHandler' implementation processes the results.
에서 V1의 setBucketAcl
~ V2의 acl
메서드 PutBucketAclRequest.builder()
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); AccessControlList acl = new AccessControlList(); acl.grantPermission(GroupGrantee.AllUsers, Permission.Read); s3ClientV1.setBucketAcl("bucket-name", acl); // SDK V2 S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); PutBucketAclRequest request = PutBucketAclRequest.builder() .bucket("bucket-name") .acl(BucketCannedACL.PRIVATE) .build(); s3ClientV2.putBucketAcl(request);
에서 V1의 setObjectAcl
~ V2의 acl
메서드 PutObjectAclRequest.builder()
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); AccessControlList acl = new AccessControlList(); acl.grantPermission(GroupGrantee.AllUsers, Permission.Read); s3ClientV1.setObjectAcl("bucket-name", "object-key", acl); // SDK V2 S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); PutObjectAclRequest request = PutObjectAclRequest.builder() .bucket("bucket-name") .key("object-key") .acl(ObjectCannedACL.PRIVATE) .build(); s3ClientV2.putObjectAcl(request);
V1에서 V2initiateMultipartUpload
로 createMultipartUpload
마이그레이션 예제
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("application/zip"); metadata.addUserMetadata("mykey", "myvalue"); InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest( "bucket-name", "object-key", metadata ); InitiateMultipartUploadResult initResponse = s3ClientV1.initiateMultipartUpload(initRequest); String uploadId = initResponse.getUploadId(); // SDK V2 // V1 uses ObjectMetadata methods, whereas V2 uses a simple Map. S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); CreateMultipartUploadRequest createMultipartRequest = CreateMultipartUploadRequest.builder() .bucket("my-bucket") .key("object-key") .contentType("application/zip") .metadata(Collections.singletonMap("mykey", "myvalue")) .build(); CreateMultipartUploadResponse response = s3ClientV2.createMultipartUpload(createMultipartRequest); String uploadId = response.uploadId();
구현 차이점
다음 메서드의 기본 Content-Type
헤더 값은 다음 표와 같이 다릅니다.
SDK 버전 | 메서드 | 기본Content-Type 값 |
---|---|---|
버전 1 | initiateMultipartUpload |
application/octet-stream |
버전 2 | createMultipartUpload |
binary/octet-stream |
클라이언트 빌더의 V1에서 V2setRegion
로의 region
메서드
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard().build(); s3ClientV1.setRegion(Region.getRegion(Regions.US_WEST_2)); // SDK V2 S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build();
V1의 setS3ClientOptions(S3ClientOptions clientOptions)
V2는 setS3ClientOptions
메서드와 함께 단일 S3ClientOptions
객체를 사용하는 대신 클라이언트 빌더에 옵션을 설정하는 메서드를 제공합니다.
V1에서 V2setBucketLoggingConfiguration
로 putBucketLogging
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); BucketLoggingConfiguration loggingConfig = new BucketLoggingConfiguration(); loggingConfig.setDestinationBucketName("log-bucket"); SetBucketLoggingConfigurationRequest request = new SetBucketLoggingConfigurationRequest( "source-bucket", loggingConfig ); s3ClientV1.setBucketLoggingConfiguration(request); // SDK V2 // In V2, V1's 'BucketLoggingConfiguration' is replaced by 'BucketLoggingStatus' // and 'LoggingEnabled'. S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); LoggingEnabled loggingEnabled = LoggingEnabled.builder() .targetBucket("log-bucket") .build(); BucketLoggingStatus loggingStatus = BucketLoggingStatus.builder() .loggingEnabled(loggingEnabled) .build(); PutBucketLoggingRequest request = PutBucketLoggingRequest.builder() .bucket("source-bucket") .bucketLoggingStatus(loggingStatus) .build(); s3ClientV2.putBucketLogging(request);
V1에서 V2setBucketLifecycleConfiguration
로 putBucketLifecycleConfiguration
// SDK V1 BucketLifecycleConfiguration.Rule rule = new BucketLifecycleConfiguration.Rule() .withId("Archive and Delete Rule") .withPrefix("documents/") .withStatus(BucketLifecycleConfiguration.ENABLED) .withTransitions(Arrays.asList( new Transition() .withDays(30) .withStorageClass(StorageClass.StandardInfrequentAccess.toString()), new Transition() .withDays(90) .withStorageClass(StorageClass.Glacier.toString()) )) .withExpirationInDays(365); BucketLifecycleConfiguration configuration = new BucketLifecycleConfiguration() .withRules(Arrays.asList(rule)); s3ClientV1.setBucketLifecycleConfiguration("my-bucket", configuration); // SDK V2 LifecycleRule rule = LifecycleRule.builder() .id("Archive and Delete Rule") .filter(LifecycleRuleFilter.builder() .prefix("documents/") .build()) .status(ExpirationStatus.ENABLED) .transitions(Arrays.asList( Transition.builder() .days(30) .storageClass(TransitionStorageClass.STANDARD_IA) .build(), Transition.builder() .days(90) .storageClass(TransitionStorageClass.GLACIER) .build() )) .expiration(LifecycleExpiration.builder() .days(365) .build()) .build(); PutBucketLifecycleConfigurationRequest request = PutBucketLifecycleConfigurationRequest.builder() .bucket("my-bucket") .lifecycleConfiguration(BucketLifecycleConfiguration.builder() .rules(rule) .build()) .build(); s3ClientV2.putBucketLifecycleConfiguration(request);
V1에서 V2setBucketTaggingConfiguration
로 putBucketTagging
// SDK V1 List<TagSet> tagsets = new ArrayList<>(); TagSet tagSet = new TagSet(); tagSet.setTag("key1", "value1"); tagSet.setTag("key2", "value2"); tagsets.add(tagSet); BucketTaggingConfiguration bucketTaggingConfiguration = new BucketTaggingConfiguration(); bucketTaggingConfiguration.setTagSets(tagsets); SetBucketTaggingConfigurationRequest request = new SetBucketTaggingConfigurationRequest( "my-bucket", bucketTaggingConfiguration ); s3ClientV1.setBucketTaggingConfiguration(request); // SDK V2 Tagging tagging = Tagging.builder() .tagSet(Arrays.asList( Tag.builder() .key("key1") .value("value1") .build(), Tag.builder() .key("key2") .value("value2") .build() )) .build(); PutBucketTaggingRequest request = PutBucketTaggingRequest.builder() .bucket("my-bucket") .tagging(tagging) .build(); s3ClientV2.putBucketTagging(request);
수동 마이그레이션이 필요한 V1 클래스
V1에서 V2AccessControlList
로 AccessControlPolicy
// SDK V1 AccessControlList aclV1 = new AccessControlList(); aclV1.setOwner(new Owner("owner-id", "owner-name")); aclV1.grantPermission(GroupGrantee.AllUsers, Permission.Read); // SDK V2 // To migrate from V1 to V2, replace direct 'AccessControlList' modifications with an // 'AccessControlPolicy.builder()' that contains both owner information and grants. // Note that V2's approach requires building the complete permission set upfront rather than modifying permissions incrementally. AccessControlPolicy acpV2 = AccessControlPolicy.builder() .owner(Owner.builder() .id("owner-id") .displayName("owner-name") .build()) .grants(Arrays.asList( Grant.builder() .grantee(Grantee.builder() .type(Type.GROUP) .uri("http://acs.amazonaws.com/groups/global/AllUsers") .build()) .permission(Permission.READ) .build() )) .build();
V1의 CannedAccessControlList
열거형에서 V2의 ObjectCannedACL
열거형 BucketCannedACL
및 열거형으로
// SDK V1 // In V1, 'CannedAccessControlList' is an enumeration of predefined ACLs. AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard().build(); // Creating a bucket. s3ClientV1.setBucketAcl("bucket-name", CannedAccessControlList.PublicRead); // Creating an object. PutObjectRequest putObjectRequest = new PutObjectRequest("bucket-name", "object-key", file) .withCannedAcl(CannedAccessControlList.PublicRead); s3ClientV1.putObject(putObjectRequest); // SDK V2 // V2 replaces V1's 'CannedAccessControlList' with 'BucketCannedACL' for buckets and 'ObjectCannedACL' for objects. S3Client s3ClientV2 = S3Client.builder().build(); // Creating a bucket. PutBucketAclRequest bucketRequest = PutBucketAclRequest.builder() .bucket("bucket-name") .acl(BucketCannedACL.PRIVATE) .build(); s3ClientV2.putBucketAcl(bucketRequest); // Creating an object. PutObjectRequest objectRequest = PutObjectRequest.builder() .bucket("bucket-name") .key("object-key") .acl(ObjectCannedACL.PUBLIC_READ) .build(); s3ClientV2.putObject(objectRequest, RequestBody.fromFile(file));
V1에서 V2BucketNotificationConfiguration
로 NotificationConfiguration
//SDK V1 BucketNotificationConfiguration notificationConfig = new BucketNotificationConfiguration(); // Adding configurations by name notificationConfig.addConfiguration("lambdaConfig", new LambdaConfiguration("arn:aws:lambda:function", "s3:ObjectCreated:")); notificationConfig.addConfiguration("topicConfig", new TopicConfiguration("arn:aws:sns:topic", "s3:ObjectRemoved:")); notificationConfig.addConfiguration("queueConfig", new QueueConfiguration("arn:aws:sqs:queue", "s3:ObjectRestore:*")); s3Client.setBucketNotificationConfiguration("bucket", notificationConfig); // SDK V2 // In V2, V1's BucketNotificationConfiguration is renamed to NotificationConfiguration. // V2 contains no common abstract class for LambdaFunction/Topic/Queue configurations. NotificationConfiguration notificationConfig = NotificationConfiguration.builder() .lambdaFunctionConfigurations( LambdaFunctionConfiguration.builder() .lambdaFunctionArn("arn:aws:lambda:function") .events(Event.valueOf("s3:ObjectCreated:")) .build()) .topicConfigurations( TopicConfiguration.builder() .topicArn("arn:aws:sns:topic") .events(Event.valueOf("s3:ObjectRemoved:")) .build()) .queueConfigurations( QueueConfiguration.builder() .queueArn("arn:aws:sqs:queue") .events(Event.valueOf("s3:ObjectRestore:*")) .build()) .build(); s3Client.putBucketNotificationConfiguration(req -> req .bucket("bucket") .notificationConfiguration(notificationConfig));
요청 빌더에서 V1의 MultiFactorAuthentication
~ V2의 mfa
메서드
// SDK V1 AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard() .withRegion(Regions.US_WEST_2) .build(); BucketVersioningConfiguration versioningConfig = new BucketVersioningConfiguration() .withStatus(BucketVersioningConfiguration.ENABLED); // Create an MFA configuration object. MultiFactorAuthentication mfa = new MultiFactorAuthentication( "arn:aws:iam::1234567890:mfa/user", "123456" ); // Create the request object. SetBucketVersioningConfigurationRequest request = new SetBucketVersioningConfigurationRequest( "bucket-name", versioningConfig, mfa ); // Send the request. s3ClientV1.setBucketVersioningConfiguration(request); // SDK V2 // V2 replaces V1's MultiFactorAuthentication POJO with parameters you set on the request builder. S3Client s3ClientV2 = S3Client.builder() .region(Region.US_WEST_2) .build(); PutBucketVersioningRequest request = PutBucketVersioningRequest.builder() .bucket("bucket-name") .versioningConfiguration(VersioningConfiguration.builder() .status(BucketVersioningStatus.ENABLED) .build()) .mfa("arn:aws:iam::1234567890:mfa/user 123456") // Single method takes both MFA erial number and token. .build(); s3ClientV2.putBucketVersioning(request);