レスポンスの送信
Ktorを使用すると、受信したリクエストを処理し、ルートハンドラー内でレスポンスを送信できます。プレーンテキスト、HTMLドキュメントやテンプレート、シリアライズされたデータオブジェクトなど、さまざまな種類のレスポンスを送信できます。各レスポンスに対して、コンテンツタイプ、ヘッダー、Cookieなどのさまざまなレスポンスパラメーターを設定することもできます。
ルートハンドラー内では、レスポンスを操作するために以下のAPIが利用可能です:
- 特定のコンテンツタイプを送信するための関数群(例: call.respondText、call.respondHtmlなど)。
- call.respond関数は、レスポンス内にあらゆるデータを送信することを可能にします。例えば、ContentNegotiationプラグインが有効な場合、特定のフォーマットでシリアライズされたデータオブジェクトを送信できます。
- call.responseプロパティは、レスポンスパラメーターへのアクセスを提供し、ステータスコードの設定、ヘッダーの追加、Cookieの設定を可能にするApplicationResponseオブジェクトを返します。
- call.respondRedirectは、リダイレクトを追加する機能を提供します。
レスポンスペイロードの設定
プレーンテキスト
レスポンスでプレーンテキストを送信するには、call.respondText関数を使用します。
get("/") {
call.respondText("Hello, world!")
}
HTML
Ktorは、クライアントにHTMLレスポンスを送信する2つの主要な方法を提供します:
- Kotlin HTML DSLを使用してHTMLを構築する。
- FreeMarker、VelocityなどのJVMテンプレートエンジンを使用する。
Kotlin DSLを使用して構築したHTMLを送信するには、call.respondHtml関数を使用します。
routing {
get("/") {
val name = "Ktor"
call.respondHtml(HttpStatusCode.OK) {
head {
title {
+name
}
}
body {
h1 {
+"Hello from $name!"
}
}
}
}
}
レスポンスでテンプレートを送信するには、call.respond関数を特定のコンテンツとともに呼び出します...
get("/index") {
val sampleUser = User(1, "John")
call.respond(FreeMarkerContent("index.ftl", mapOf("user" to sampleUser)))
}
...または適切なcall.respondTemplate関数を使用します:
get("/index") {
val sampleUser = User(1, "John")
call.respondTemplate("index.ftl", mapOf("user" to sampleUser))
}
詳細については、Templatingヘルプセクションを参照してください。
オブジェクト
Ktorでデータオブジェクトのシリアライズを有効にするには、ContentNegotiationプラグインをインストールし、必要なコンバーター(例: JSON)を登録する必要があります。その後、call.respond関数を使用してレスポンスでデータオブジェクトを渡すことができます:
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
ヘッダーを追加することで、このファイルをダウンロード可能にする方法を示しています:
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を呼び出します。事前に定義されたステータスコード値を渡すことができます...
get("/") {
call.response.status(HttpStatusCode.OK)
}
...またはカスタムステータスコードを指定できます:
get("/") {
call.response.status(HttpStatusCode(418, "I'm a tea pot"))
}
ペイロードを送信する関数には、ステータスコードを指定するためのオーバーロードがあることに注意してください。
コンテンツタイプ
インストールされているContentNegotiationプラグインを使用すると、Ktorはレスポンスのコンテンツタイプを自動的に選択します。必要に応じて、対応するパラメーターを渡すことで、コンテンツタイプを手動で指定できます。例えば、以下のコードスニペットのcall.respondText
関数は、ContentType.Text.Plain
をパラメーターとして受け入れます:
get("/") {
call.respondText("Hello, world!", ContentType.Text.Plain, HttpStatusCode.OK)
}
ヘッダー
レスポンスで特定のヘッダーを送信するには、いくつかの方法があります:
ApplicationResponse.headersコレクションにヘッダーを追加します:
kotlinget("/") { call.response.headers.append(HttpHeaders.ETag, "7c876b7e") }
ApplicationResponse.header関数を呼び出します:
kotlinget("/") { call.response.header(HttpHeaders.ETag, "7c876b7e") }
具体的なヘッダーを指定するための専用関数を使用します(例えば、
ApplicationResponse.etag
、ApplicationResponse.link
などです)。kotlinget("/") { call.response.etag("7c876b7e") }
カスタムヘッダーを追加するには、その名前を文字列値として上記のいずれかの関数に渡します。例えば:
kotlinget("/") { call.response.header("Custom-Header", "Some value") }
各レスポンスに標準の
Server
およびDate
ヘッダーを追加するには、DefaultHeadersプラグインをインストールします。
Cookie
レスポンスで送信されるCookieを設定するには、ApplicationResponse.cookiesプロパティを使用します:
get("/") {
call.response.cookies.append("yummy_cookie", "choco")
}
Ktorは、Cookieを使用してセッションを処理する機能も提供します。詳細については、Sessionsセクションを参照してください。
リダイレクト
リダイレクトレスポンスを生成するには、respondRedirect関数を呼び出します:
get("/") {
call.respondRedirect("/moved", permanent = true)
}
get("/moved") {
call.respondText("Moved content")
}