LoginSignup
1
0

More than 3 years have passed since last update.

[Ktor]multipart/form-dataでファイルを取得

Last updated at Posted at 2020-01-09

やりたかったこと

サーバサイドkotlinでKtorを使ってmultipart/form-data形式のファイルを取得したい。
画像でもtxtでもjsonでもdatでも。

実装

※動作確認したいだけならResourceとServiceに分ける必要はないです

hogeResource.kt
fun.Route.hoge(hogeService: HogeService) {
   route("hoge") {
       post("/") {
           val multiPartData = call.receiveMultiPart() 
           val res = hogeService.addHoge(multiPartData)
           call.respond(HttpStatusCode.OK, res)
       }
   }
}
hogeService.kt
    suspend fun addHoge(multipartData: MultiPartData) : Hoge {
        val file = makeFile(multipartData) ?: throw Exception()

        // この辺は今回関係ないので中略。
        // ファイルからデータを取得してExposedを使いDBに登録してます。

        return getHoge(hoge.id)
    }

    private fun makeFile(multipartData: MultiPartData) : File? {
        // ファイル生成(別にTempFileである必要はないので好みで)
        val file = File.createTempFile("tmp_", ".json")
        val part = multipartData.readPart() ?: return null
        if (part !is PartData.FileItem) return null 
        // ファイル内容の書き込み
        part.streamProvider().use { inputStream ->
            file.outputStream().buffered().use {
                inputStream.copyTo(it)
            }
        }
        return file
   }

・ファイル名
元ファイルから変えないならPartData.FileItem.originalFileNameを使えばよいと思います。

・FileItemの取得
ktorの公式サンプルだとmultipart.forEachPartを使っていますが
ファイルしか受信しないのであればmultipartData.readPart()で短く書けます。
(但し、FileItemだという型チェックはしてあげないといけません)

multipart/form-dataにファイル以外の別のパラメータも含んでいる場合はこんな感じ。

hogeService.kt
var hogeID = 0
var hogeName = ""
multiPartData.forEachPart { part ->
    when (part) {
        is PartData.FormItem -> {
           when (it.name) {
               "hogeID"   -> hogeID   = it.value.toInt()
               "hogeName" -> hogeName = it.value
           }
        }
        is PartData.FileItem -> {
           //(略)
        }
    }
}

いちいちJsonファイルをパースしてDBに登録、なんてことは滅多にやることではないので、
画像か、datで受け取って復号化みたいな用途が本来の使い方ですかね。
あとは、AmazonS3に突っ込むとか。

参考

Client Multipart
https://ktor.io/samples/other/client-multipart.html

PartData
https://api.ktor.io/1.3.0-rc2/io.ktor.http.content/-part-data/index.html

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0