

Doc AWS SDK 예제 GitHub 리포지토리에서 더 많은 SDK 예제를 사용할 수 있습니다. [AWS](https://github.com/awsdocs/aws-doc-sdk-examples) 

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# SDK for Kotlin을 사용한 Amazon S3 예제
<a name="kotlin_1_s3_code_examples"></a>

다음 코드 예제에서는 Amazon S3에서 AWS SDK for Kotlin을 사용하여 작업을 수행하고 일반적인 시나리오를 구현하는 방법을 보여줍니다.

*기본 사항*은 서비스 내에서 필수 작업을 수행하는 방법을 보여주는 코드 예제입니다.

*작업*은 대규모 프로그램에서 발췌한 코드이며 컨텍스트에 맞춰 실행해야 합니다. 작업은 개별 서비스 함수를 직접 호출하는 방법을 보여주며, 관련 시나리오의 컨텍스트에 맞는 작업을 볼 수 있습니다.

*시나리오*는 동일한 서비스 내에서 또는 다른 AWS 서비스와 결합된 상태에서 여러 함수를 직접적으로 호출하여 특정 태스크를 수행하는 방법을 보여주는 코드 예제입니다.

각 예시에는 전체 소스 코드에 대한 링크가 포함되어 있으며, 여기에서 컨텍스트에 맞춰 코드를 설정하고 실행하는 방법에 대한 지침을 찾을 수 있습니다.

**Topics**
+ [기본 사항](#basics)
+ [작업](#actions)
+ [시나리오](#scenarios)

## 기본 사항
<a name="basics"></a>

### 기본 사항 알아보기
<a name="s3_Scenario_GettingStarted_kotlin_1_topic"></a>

다음 코드 예제에서는 다음과 같은 작업을 수행하는 방법을 보여줍니다.
+ 버킷을 만들고 버킷에 파일을 업로드합니다.
+ 버킷에서 객체를 다운로드합니다.
+ 버킷의 하위 폴더에 객체를 복사합니다.
+ 버킷의 객체를 나열합니다.
+ 버킷 객체와 버킷을 삭제합니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예제 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예제를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun main(args: Array<String>) {
    val usage = """
    Usage:
        <bucketName> <key> <objectPath> <savePath> <toBucket>

    Where:
        bucketName - The Amazon S3 bucket to create.
        key - The key to use.
        objectPath - The path where the file is located (for example, C:/AWS/book2.pdf).   
        savePath - The path where the file is saved after it's downloaded (for example, C:/AWS/book2.pdf).     
        toBucket - An Amazon S3 bucket to where an object is copied to (for example, C:/AWS/book2.pdf). 
        """

    if (args.size != 4) {
        println(usage)
        exitProcess(1)
    }

    val bucketName = args[0]
    val key = args[1]
    val objectPath = args[2]
    val savePath = args[3]
    val toBucket = args[4]

    // Create an Amazon S3 bucket.
    createBucket(bucketName)

    // Update a local file to the Amazon S3 bucket.
    putObject(bucketName, key, objectPath)

    // Download the object to another local file.
    getObjectFromMrap(bucketName, key, savePath)

    // List all objects located in the Amazon S3 bucket.
    listBucketObs(bucketName)

    // Copy the object to another Amazon S3 bucket
    copyBucketOb(bucketName, key, toBucket)

    // Delete the object from the Amazon S3 bucket.
    deleteBucketObs(bucketName, key)

    // Delete the Amazon S3 bucket.
    deleteBucket(bucketName)
    println("All Amazon S3 operations were successfully performed")
}

suspend fun createBucket(bucketName: String) {
    val request =
        CreateBucketRequest {
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.createBucket(request)
        println("$bucketName is ready")
    }
}

suspend fun putObject(
    bucketName: String,
    objectKey: String,
    objectPath: String,
) {
    val metadataVal = mutableMapOf<String, String>()
    metadataVal["myVal"] = "test"

    val request =
        PutObjectRequest {
            bucket = bucketName
            key = objectKey
            metadata = metadataVal
            this.body = Paths.get(objectPath).asByteStream()
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        val response = s3.putObject(request)
        println("Tag information is ${response.eTag}")
    }
}

suspend fun getObjectFromMrap(
    bucketName: String,
    keyName: String,
    path: String,
) {
    val request =
        GetObjectRequest {
            key = keyName
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.getObject(request) { resp ->
            val myFile = File(path)
            resp.body?.writeToFile(myFile)
            println("Successfully read $keyName from $bucketName")
        }
    }
}

suspend fun listBucketObs(bucketName: String) {
    val request =
        ListObjectsRequest {
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->

        val response = s3.listObjects(request)
        response.contents?.forEach { myObject ->
            println("The name of the key is ${myObject.key}")
            println("The owner is ${myObject.owner}")
        }
    }
}

suspend fun copyBucketOb(
    fromBucket: String,
    objectKey: String,
    toBucket: String,
) {
    var encodedUrl = ""
    try {
        encodedUrl = URLEncoder.encode("$fromBucket/$objectKey", StandardCharsets.UTF_8.toString())
    } catch (e: UnsupportedEncodingException) {
        println("URL could not be encoded: " + e.message)
    }

    val request =
        CopyObjectRequest {
            copySource = encodedUrl
            bucket = toBucket
            key = objectKey
        }
    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.copyObject(request)
    }
}

suspend fun deleteBucketObs(
    bucketName: String,
    objectName: String,
) {
    val objectId =
        ObjectIdentifier {
            key = objectName
        }

    val delOb =
        Delete {
            objects = listOf(objectId)
        }

    val request =
        DeleteObjectsRequest {
            bucket = bucketName
            delete = delOb
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.deleteObjects(request)
        println("$objectName was deleted from $bucketName")
    }
}

suspend fun deleteBucket(bucketName: String?) {
    val request =
        DeleteBucketRequest {
            bucket = bucketName
        }
    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.deleteBucket(request)
        println("The $bucketName was successfully deleted!")
    }
}
```
+ API 세부 정보는 *AWS SDK for Kotlin API 참조*의 다음 주제를 참조하세요.
  + [CopyObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)
  + [CreateBucket](https://sdk.amazonaws.com/kotlin/api/latest/index.html)
  + [DeleteBucket](https://sdk.amazonaws.com/kotlin/api/latest/index.html)
  + [DeleteObjects](https://sdk.amazonaws.com/kotlin/api/latest/index.html)
  + [GetObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)
  + [ListObjectsV2](https://sdk.amazonaws.com/kotlin/api/latest/index.html)
  + [PutObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)

## 작업
<a name="actions"></a>

### `CopyObject`
<a name="s3_CopyObject_kotlin_1_topic"></a>

다음 코드 예시는 `CopyObject`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun copyBucketObject(
    fromBucket: String,
    objectKey: String,
    toBucket: String,
) {
    var encodedUrl = ""
    try {
        encodedUrl = URLEncoder.encode("$fromBucket/$objectKey", StandardCharsets.UTF_8.toString())
    } catch (e: UnsupportedEncodingException) {
        println("URL could not be encoded: " + e.message)
    }

    val request =
        CopyObjectRequest {
            copySource = encodedUrl
            bucket = toBucket
            key = objectKey
        }
    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.copyObject(request)
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [CopyObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `CreateBucket`
<a name="s3_CreateBucket_kotlin_1_topic"></a>

다음 코드 예시는 `CreateBucket`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun createNewBucket(bucketName: String) {
    val request =
        CreateBucketRequest {
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.createBucket(request)
        println("$bucketName is ready")
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [CreateBucket](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `CreateMultiRegionAccessPoint`
<a name="s3_CreateMultiRegionAccessPoint_kotlin_1_topic"></a>

다음 코드 예시는 `CreateMultiRegionAccessPoint`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.
us-west-2 리전으로 요청을 보내도록 S3 제어 클라이언트를 구성합니다.  

```
        suspend fun createS3ControlClient(): S3ControlClient {
            // Configure your S3ControlClient to send requests to US West (Oregon).
            val s3Control = S3ControlClient.fromEnvironment {
                region = "us-west-2"
            }
            return s3Control
        }
```
다중 리전 액세스 포인트를 생성합니다.  

```
    suspend fun createMrap(
        s3Control: S3ControlClient,
        accountIdParam: String,
        bucketName1: String,
        bucketName2: String,
        mrapName: String,
    ): String {
        println("Creating MRAP ...")
        val createMrapResponse: CreateMultiRegionAccessPointResponse =
            s3Control.createMultiRegionAccessPoint {
                accountId = accountIdParam
                clientToken = UUID.randomUUID().toString()
                details {
                    name = mrapName
                    regions = listOf(
                        Region {
                            bucket = bucketName1
                        },
                        Region {
                            bucket = bucketName2
                        },
                    )
                }
            }
        val requestToken: String? = createMrapResponse.requestTokenArn

        // Use the request token to check for the status of the CreateMultiRegionAccessPoint operation.
        if (requestToken != null) {
            waitForSucceededStatus(s3Control, requestToken, accountIdParam)
            println("MRAP created")
        }

        val getMrapResponse =
            s3Control.getMultiRegionAccessPoint(
                input = GetMultiRegionAccessPointRequest {
                    accountId = accountIdParam
                    name = mrapName
                },
            )
        val mrapAlias = getMrapResponse.accessPoint?.alias
        return "arn:aws:s3::$accountIdParam:accesspoint/$mrapAlias"
    }
```
다중 리전 액세스 포인트가 사용 가능해질 때까지 기다립니다.  

```
        suspend fun waitForSucceededStatus(
            s3Control: S3ControlClient,
            requestToken: String,
            accountIdParam: String,
            timeBetweenChecks: Duration = 1.minutes,
        ) {
            var describeResponse: DescribeMultiRegionAccessPointOperationResponse
            describeResponse = s3Control.describeMultiRegionAccessPointOperation(
                input = DescribeMultiRegionAccessPointOperationRequest {
                    accountId = accountIdParam
                    requestTokenArn = requestToken
                },
            )

            var status: String? = describeResponse.asyncOperation?.requestStatus
            while (status != "SUCCEEDED") {
                delay(timeBetweenChecks)
                describeResponse = s3Control.describeMultiRegionAccessPointOperation(
                    input = DescribeMultiRegionAccessPointOperationRequest {
                        accountId = accountIdParam
                        requestTokenArn = requestToken
                    },
                )
                status = describeResponse.asyncOperation?.requestStatus
                println(status)
            }
        }
```
+  자세한 내용은 [AWS SDK for Kotlin 개발자 안내서](https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/use-services-s3-mrap.html)를 참조하세요.
+  API 세부 정보는 **Kotlin API 참조용AWS SDK의 [CreateMultiRegionAccessPoint](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `DeleteBucketPolicy`
<a name="s3_DeleteBucketPolicy_kotlin_1_topic"></a>

다음 코드 예시는 `DeleteBucketPolicy`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun deleteS3BucketPolicy(bucketName: String?) {
    val request =
        DeleteBucketPolicyRequest {
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.deleteBucketPolicy(request)
        println("Done!")
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [DeleteBucketPolicy](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `DeleteObjects`
<a name="s3_DeleteObjects_kotlin_1_topic"></a>

다음 코드 예시는 `DeleteObjects`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun deleteBucketObjects(
    bucketName: String,
    objectName: String,
) {
    val objectId =
        ObjectIdentifier {
            key = objectName
        }

    val delOb =
        Delete {
            objects = listOf(objectId)
        }

    val request =
        DeleteObjectsRequest {
            bucket = bucketName
            delete = delOb
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.deleteObjects(request)
        println("$objectName was deleted from $bucketName")
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [DeleteObjects](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `GetBucketPolicy`
<a name="s3_GetBucketPolicy_kotlin_1_topic"></a>

다음 코드 예시는 `GetBucketPolicy`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun getPolicy(bucketName: String): String? {
    println("Getting policy for bucket $bucketName")

    val request =
        GetBucketPolicyRequest {
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        val policyRes = s3.getBucketPolicy(request)
        return policyRes.policy
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [GetBucketPolicy](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `GetObject`
<a name="s3_GetObject_kotlin_1_topic"></a>

다음 코드 예시는 `GetObject`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun getObjectBytes(
    bucketName: String,
    keyName: String,
    path: String,
) {
    val request =
        GetObjectRequest {
            key = keyName
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.getObject(request) { resp ->
            val myFile = File(path)
            resp.body?.writeToFile(myFile)
            println("Successfully read $keyName from $bucketName")
        }
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [GetObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `GetObjectAcl`
<a name="s3_GetObjectAcl_kotlin_1_topic"></a>

다음 코드 예시는 `GetObjectAcl`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun getBucketACL(
    objectKey: String,
    bucketName: String,
) {
    val request =
        GetObjectAclRequest {
            bucket = bucketName
            key = objectKey
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        val response = s3.getObjectAcl(request)
        response.grants?.forEach { grant ->
            println("Grant permission is ${grant.permission}")
        }
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [GetObjectAcl](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `ListObjectsV2`
<a name="s3_ListObjectsV2_kotlin_1_topic"></a>

다음 코드 예시는 `ListObjectsV2`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun listBucketObjects(bucketName: String) {
    val request =
        ListObjectsRequest {
            bucket = bucketName
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        val response = s3.listObjects(request)
        response.contents?.forEach { myObject ->
            println("The name of the key is ${myObject.key}")
            println("The object is ${myObject.size?.let { calKb(it) }} KBs")
            println("The owner is ${myObject.owner}")
        }
    }
}

private fun calKb(intValue: Long): Long = intValue / 1024
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [ListObjectsV2](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `PutBucketAcl`
<a name="s3_PutBucketAcl_kotlin_1_topic"></a>

다음 코드 예시는 `PutBucketAcl`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun setBucketAcl(
    bucketName: String,
    idVal: String,
) {
    val myGrant =
        Grantee {
            id = idVal
            type = Type.CanonicalUser
        }

    val ownerGrant =
        Grant {
            grantee = myGrant
            permission = Permission.FullControl
        }

    val grantList = mutableListOf<Grant>()
    grantList.add(ownerGrant)

    val ownerOb =
        Owner {
            id = idVal
        }

    val acl =
        AccessControlPolicy {
            owner = ownerOb
            grants = grantList
        }

    val request =
        PutBucketAclRequest {
            bucket = bucketName
            accessControlPolicy = acl
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        s3.putBucketAcl(request)
        println("An ACL was successfully set on $bucketName")
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [PutBucketAcl](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

### `PutObject`
<a name="s3_PutObject_kotlin_1_topic"></a>

다음 코드 예시는 `PutObject`의 사용 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

```
suspend fun putS3Object(
    bucketName: String,
    objectKey: String,
    objectPath: String,
) {
    val metadataVal = mutableMapOf<String, String>()
    metadataVal["myVal"] = "test"

    val request =
        PutObjectRequest {
            bucket = bucketName
            key = objectKey
            metadata = metadataVal
            body = File(objectPath).asByteStream()
        }

    S3Client.fromEnvironment { region = "us-east-1" }.use { s3 ->
        val response = s3.putObject(request)
        println("Tag information is ${response.eTag}")
    }
}
```
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [PutObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.

## 시나리오
<a name="scenarios"></a>

### 미리 서명된 URL 생성
<a name="s3_Scenario_PresignedUrl_kotlin_1_topic"></a>

다음 코드 예제에서는 Amazon S3에 대해 미리 서명된 URL을 생성하고 객체를 업로드하는 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.
미리 서명된 `GetObject` 요청을 만들고 URL을 사용하여 객체를 다운로드합니다.  

```
suspend fun getObjectPresigned(
    s3: S3Client,
    bucketName: String,
    keyName: String,
): String {
    // Create a GetObjectRequest.
    val unsignedRequest =
        GetObjectRequest {
            bucket = bucketName
            key = keyName
        }

    // Presign the GetObject request.
    val presignedRequest = s3.presignGetObject(unsignedRequest, 24.hours)

    // Use the URL from the presigned HttpRequest in a subsequent HTTP GET request to retrieve the object.
    val objectContents = URL(presignedRequest.url.toString()).readText()

    return objectContents
}
```
고급 옵션을 사용하여 `GetObject` 미리 서명된 요청을 생성합니다.  

```
suspend fun getObjectPresignedMoreOptions(
    s3: S3Client,
    bucketName: String,
    keyName: String,
): HttpRequest {
    // Create a GetObjectRequest.
    val unsignedRequest =
        GetObjectRequest {
            bucket = bucketName
            key = keyName
        }

    // Presign the GetObject request.
    val presignedRequest =
        s3.presignGetObject(unsignedRequest, signer = CrtAwsSigner) {
            signingDate = Instant.now() + 12.hours // Presigned request can be used 12 hours from now.
            algorithm = AwsSigningAlgorithm.SIGV4_ASYMMETRIC
            signatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS
            expiresAfter = 8.hours // Presigned request expires 8 hours later.
        }
    return presignedRequest
}
```
미리 서명된 `PutObject` 요청을 만들고 이를 사용하여 객체를 업로드합니다.  

```
suspend fun putObjectPresigned(
    s3: S3Client,
    bucketName: String,
    keyName: String,
    content: String,
) {
    // Create a PutObjectRequest.
    val unsignedRequest =
        PutObjectRequest {
            bucket = bucketName
            key = keyName
        }

    // Presign the request.
    val presignedRequest = s3.presignPutObject(unsignedRequest, 24.hours)

    // Use the URL and any headers from the presigned HttpRequest in a subsequent HTTP PUT request to retrieve the object.
    // Create a PUT request using the OKHttpClient API.
    val putRequest =
        Request
            .Builder()
            .url(presignedRequest.url.toString())
            .apply {
                presignedRequest.headers.forEach { key, values ->
                    header(key, values.joinToString(", "))
                }
            }.put(content.toRequestBody())
            .build()

    val response = OkHttpClient().newCall(putRequest).execute()
    assert(response.isSuccessful)
}
```
+  자세한 내용은 [AWS SDK for Kotlin 개발자 안내서](https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/presign-requests.html)를 참조하세요.

### 사진을 관리하기 위한 서버리스 애플리케이션 만들기
<a name="cross_PAM_kotlin_1_topic"></a>

다음 코드 예시에서는 사용자가 레이블을 사용하여 사진을 관리할 수 있는 서버리스 애플리케이션을 생성하는 방법을 보여줍니다.

**SDK for Kotlin**  
 Amazon Rekognition을 사용하여 이미지에서 레이블을 감지하고 나중에 검색할 수 있도록 저장하는 사진 자산 관리 애플리케이션을 개발하는 방법을 보여줍니다.  
전체 소스 코드와 설정 및 실행 방법에 대한 지침은 [GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/usecases/creating_pam)에서 전체 예제를 참조하세요.  
이 예제의 출처에 대한 자세한 내용은 [AWS  커뮤니티](https://community.aws/posts/cloud-journeys/01-serverless-image-recognition-app)의 게시물을 참조하세요.  

**이 예제에서 사용되는 서비스**
+ API Gateway
+ DynamoDB
+ Lambda
+ Amazon Rekognition
+ Amazon S3
+ Amazon SNS

### 이미지에서 객체 감지
<a name="cross_RekognitionPhotoAnalyzer_kotlin_1_topic"></a>

다음 코드 예제에서는 Amazon Rekognition을 사용하여 이미지에서 범주별 객체를 감지하는 앱을 구축하는 방법을 보여줍니다.

**SDK for Kotlin**  
 Amazon Rekognition Kotlin API를 사용하여 Amazon Simple Storage Service(Amazon S3) 버킷에 있는 이미지에서 범주별로 객체를 식별하기 위해 Amazon Rekognition을 사용하여 앱을 만드는 방법을 보여줍니다. 이 앱은 Amazon Simple Email Service(Amazon SES)를 사용하여 결과와 함께 이메일 알림을 관리자에게 보냅니다.  
 전체 소스 코드와 설정 및 실행 방법에 대한 지침은 [GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/usecases/creating_photo_analyzer_app)에서 전체 예제를 참조하세요.  

**이 예제에서 사용되는 서비스**
+ Amazon Rekognition
+ Amazon S3
+ Amazon SES

### 다중 리전 액세스 포인트에서 객체 생성
<a name="s3_GetObject_MRAP_kotlin_1_topic"></a>

다음 코드 예제에서는 다중 리전 액세스 포인트에서 객체를 가져오는 방법을 보여줍니다.

**SDK for Kotlin**  
 GitHub에 더 많은 내용이 있습니다. [AWS 코드 예 리포지토리](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/s3#code-examples)에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.
비대칭 Sigv4(Sigv4a) 서명 알고리즘을 사용하도록 S3 클라이언트를 구성합니다.  

```
        suspend fun createS3Client(): S3Client {
            // Configure your S3Client to use the Asymmetric SigV4 (SigV4a) signing algorithm.
            val sigV4aScheme = SigV4AsymmetricAuthScheme(DefaultAwsSigner)
            val s3 = S3Client.fromEnvironment {
                authSchemes = listOf(sigV4aScheme)
            }
            return s3
        }
```
버킷 이름 대신 다중 리전 액세스 포인트 ARN을 사용하여 객체를 가져옵니다.  

```
    suspend fun getObjectFromMrap(
        s3: S3Client,
        mrapArn: String,
        keyName: String,
    ): String? {
        val request = GetObjectRequest {
            bucket = mrapArn // Use the ARN instead of the bucket name for object operations.
            key = keyName
        }

        var stringObj: String? = null
        s3.getObject(request) { resp ->
            stringObj = resp.body?.decodeToString()
            if (stringObj != null) {
                println("Successfully read $keyName from $mrapArn")
            }
        }
        return stringObj
    }
```
+  자세한 내용은 [AWS SDK for Kotlin 개발자 안내서](https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/use-services-s3-mrap.html)를 참조하세요.
+  API 세부 정보는 *AWS SDK for Kotlin API 참조*의 [GetObject](https://sdk.amazonaws.com/kotlin/api/latest/index.html)를 참조하세요.