Skip to content

レスポンスの送信

Ktorを使用すると、受信したリクエストを処理し、ルートハンドラー内でレスポンスを送信できます。プレーンテキスト、HTMLドキュメントやテンプレート、シリアライズされたデータオブジェクトなど、さまざまな種類のレスポンスを送信できます。各レスポンスに対して、コンテンツタイプ、ヘッダー、Cookieなどのさまざまなレスポンスパラメーターを設定することもできます。

ルートハンドラー内では、レスポンスを操作するために以下のAPIが利用可能です:

レスポンスペイロードの設定

プレーンテキスト

レスポンスでプレーンテキストを送信するには、call.respondText関数を使用します。

kotlin
get("/") {
    call.respondText("Hello, world!")
}

HTML

Ktorは、クライアントにHTMLレスポンスを送信する2つの主要な方法を提供します:

  • Kotlin HTML DSLを使用してHTMLを構築する。
  • FreeMarker、VelocityなどのJVMテンプレートエンジンを使用する。

Kotlin DSLを使用して構築したHTMLを送信するには、call.respondHtml関数を使用します。

kotlin
routing {
    get("/") {
        val name = "Ktor"
        call.respondHtml(HttpStatusCode.OK) {
            head {
                title {
                    +name
                }
            }
            body {
                h1 {
                    +"Hello from $name!"
                }
            }
        }
    }
}

レスポンスでテンプレートを送信するには、call.respond関数を特定のコンテンツとともに呼び出します...

kotlin
get("/index") {
    val sampleUser = User(1, "John")
    call.respond(FreeMarkerContent("index.ftl", mapOf("user" to sampleUser)))
}

...または適切なcall.respondTemplate関数を使用します:

kotlin
get("/index") {
    val sampleUser = User(1, "John")
    call.respondTemplate("index.ftl", mapOf("user" to sampleUser))
}

詳細については、Templatingヘルプセクションを参照してください。

オブジェクト

Ktorでデータオブジェクトのシリアライズを有効にするには、ContentNegotiationプラグインをインストールし、必要なコンバーター(例: JSON)を登録する必要があります。その後、call.respond関数を使用してレスポンスでデータオブジェクトを渡すことができます:

kotlin
routing {
    get("/customer/{id}") {
        val id: Int by call.parameters
        val customer: Customer = customerStorage.find { it.id == id }!!
        call.respond(customer)

完全な例はこちらで確認できます: json-kotlinx

ファイル

クライアントにファイルのコンテンツをレスポンスとして送信するには、2つのオプションがあります:

  • Fileリソースの場合、call.respondFile関数を使用します。
  • Pathリソースの場合、LocalPathContentクラスと共にcall.respond()関数を使用します。

以下のコードサンプルは、レスポンスで指定されたファイルを送信し、Content-Disposition ヘッダーを追加することで、このファイルをダウンロード可能にする方法を示しています:

kotlin
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.http.content.*
import io.ktor.server.plugins.autohead.*
import io.ktor.server.plugins.partialcontent.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import java.io.File
import java.nio.file.Path

fun Application.main() {
    install(PartialContent)
    install(AutoHeadResponse)
    routing {
        get("/download") {
            val file = File("files/ktor_logo.png")
            call.response.header(
                HttpHeaders.ContentDisposition,
                ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, "ktor_logo.png")
                    .toString()
            )
            call.respondFile(file)
        }
        get("/downloadFromPath") {
            val filePath = Path.of("files/file.txt")
            call.response.header(
                HttpHeaders.ContentDisposition,
                ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, "file.txt")
                    .toString()
            )
            call.respond(LocalPathContent(filePath))
        }
    }

このサンプルには、2つのプラグインがインストールされていることに注意してください:

  • PartialContentは、サーバーがRangeヘッダーを持つリクエストに応答し、コンテンツの一部のみを送信できるようにします。
  • AutoHeadResponseは、GETが定義されているすべてのルートに対してHEADリクエストに自動的に応答する機能を提供します。これにより、クライアントアプリケーションはContent-Lengthヘッダー値を読み取ることでファイルサイズを決定できます。

完全なコードサンプルについては、download-fileを参照してください。

生のペイロード

生のボディペイロードを送信する必要がある場合は、call.respondBytes関数を使用します。

レスポンスパラメーターの設定

ステータスコード

レスポンスのステータスコードを設定するには、ApplicationResponse.statusを呼び出します。事前に定義されたステータスコード値を渡すことができます...

kotlin
get("/") {
    call.response.status(HttpStatusCode.OK)
}

...またはカスタムステータスコードを指定できます:

kotlin
get("/") {
    call.response.status(HttpStatusCode(418, "I'm a tea pot"))
}

ペイロードを送信する関数には、ステータスコードを指定するためのオーバーロードがあることに注意してください。

コンテンツタイプ

インストールされているContentNegotiationプラグインを使用すると、Ktorはレスポンスのコンテンツタイプを自動的に選択します。必要に応じて、対応するパラメーターを渡すことで、コンテンツタイプを手動で指定できます。例えば、以下のコードスニペットのcall.respondText関数は、ContentType.Text.Plainをパラメーターとして受け入れます:

kotlin
get("/") {
    call.respondText("Hello, world!", ContentType.Text.Plain, HttpStatusCode.OK)
}

ヘッダー

レスポンスで特定のヘッダーを送信するには、いくつかの方法があります:

  • ApplicationResponse.headersコレクションにヘッダーを追加します:

    kotlin
    get("/") {
        call.response.headers.append(HttpHeaders.ETag, "7c876b7e")
    }
  • ApplicationResponse.header関数を呼び出します:

    kotlin
    get("/") {
        call.response.header(HttpHeaders.ETag, "7c876b7e")
    }
  • 具体的なヘッダーを指定するための専用関数を使用します(例えば、ApplicationResponse.etagApplicationResponse.linkなどです)。

    kotlin
    get("/") {
        call.response.etag("7c876b7e")
    }
  • カスタムヘッダーを追加するには、その名前を文字列値として上記のいずれかの関数に渡します。例えば:

    kotlin
    get("/") {
        call.response.header("Custom-Header", "Some value")
    }

各レスポンスに標準のServerおよびDateヘッダーを追加するには、DefaultHeadersプラグインをインストールします。

Cookie

レスポンスで送信されるCookieを設定するには、ApplicationResponse.cookiesプロパティを使用します:

kotlin
get("/") {
    call.response.cookies.append("yummy_cookie", "choco")
}

Ktorは、Cookieを使用してセッションを処理する機能も提供します。詳細については、Sessionsセクションを参照してください。

リダイレクト

リダイレクトレスポンスを生成するには、respondRedirect関数を呼び出します:

kotlin
get("/") {
    call.respondRedirect("/moved", permanent = true)
}

get("/moved") {
    call.respondText("Moved content")
}