Getting started S3 with Kotlin Spring Boot

jutamart kotkaew
odds.team
Published in
3 min readFeb 6, 2024

หากอยากรู้ว่า S3 คือ อะไร : https://www.blognone.com/node/101588

AWS S3 image generated by ChatGPT-4

Pre-requisite :

  1. account aws ที่มี permission in s3
  2. AWS credentials : ที่จะประกอบด้วย ACCESS_KEY_ID , SECRET_ACCESS_KEY
  3. project Kotlin springboot with Spring Web Dependency https://start.spring.io/

โดย IDE ที่ใช้จะเป็น IntelliJ

การสร้าง Bucket

การสร้าง bucket เพื่อเก็บข้อมูล โดยการตั้งชื่อจะต้องไม่ซ้ำกับชื่อ bucket ทั้งระบบของ S3 ซึ่งชื่อที่ตั้งไว้จะกลายเป็นส่วนหนึ่งของ URL สำหรับให้เข้าถึง

** โดยในตัวอย่างเป็นการตั้งค่าเป็นตามที่ S3 แนะนำ

หลังจากที่ ได้ bucket มาเรียบร้อยแล้ว ก็ทำการ สร้าง folder และสามารถ upload file ได้เลย

มาต่อกันในส่วนของ API เพื่อเรียกใช้ S3 กัน

Dependencies : Gradle Build Tool

dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("aws.sdk.kotlin:s3:1.0.40")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

Set env by edit configuration

ไปที่แถบด้านบน

Run > Edit configuration > Kotlin > file.kt

หากไม่มีทำการเพิ่ม กดปุ่ม + > Add New configuration > Kotlin

เลือก Main class: เป็น file Application.kt

set environment variable : กรอก AWS credentials จากนั้น Apply

สร้าง Controller

@RestController
@RequestMapping("/download")
public class FileController(
val downloadService:DownloadService
) {
@GetMapping("/file")
fun getFile(@RequestParam("keyName")keyName :String)
: RedirectView {
return RedirectView(downloadService
.download("ชื่อของ bucket ที่สร้าง",keyName))
}
}

สร้าง Service

class DownloadService {
fun download(bucketName: String,
keyName: String): String = runBlocking {

val s3 = S3Client.fromEnvironment() { region = "ap-southeast-1" }
val bucketName = bucketName
val keyName = keyName
val presignedUrl = getObjectPresigned(s3, bucketName, keyName)

return@runBlocking presignedUrl
}

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)
return presignedRequest.url.toString()
}
}

โดย API จะถูกเรียกด้วย path: http://localhost:8080/download/file ที่ส่ง Request Param เป็น keyName ซึ่ง keyName ที่ส่งไปนี้จะเป็น path ของ object ใน S3 (สามารถกดเข้าไปในไฟล์เพื่อ copy key มาได้เลย)

Postman call API

จากนั้นก็ทำการลองยิง Postman ตาม Path ที่ตั้งไว้ และใส่ Key และ Value ของ keyName ที่สร้างเป็น RequestParam ไว้ใน controller (path ของ object ใน S3) หรือสามารถนำ Path ไปวางที่ web browser ได้เช่นกัน

แก้ไข meta data เพื่อเปลี่ยน content type

เนื่องจากไฟล์ที่ได้ออกมายังเป็น file สำหรับ preview อยู่ สามารถแก้ไขให้สามารถ Download file ได้เลย โดยการเปลี่ยน type Metadata ใน Bucket ให้มี Value = application/octet-stream

เท่านี้เราก็สามารถDownload file จาก S3 ได้แล้วค่ะ

Sources :

Doc SDK for Kotlin : https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/home.html

Set up Enviroment in Kotlin : https://www.twilio.com/en-us/blog/set-up-env-variables-intellij-idea-java

Git Ropo : aws-doc-sdk-examples

--

--