处理路径或直接拦截管道时,将获得ApplicationCall的上下文。 该调用包含一个名为response的属性,允许发出响应。
上下文
使用路由功能时,您可以访问路由处理程序中的call属性:
routing {
get("/") {
call.respondText("Request uri: ${call.request.uri}")
}
}
当拦截请求时,拦截中的lambda处理程序也具有可用的call属性:
intercept(ApplicationCallPipeline.Call) {
if (call.request.uri == "/") {
call.respondText("Test String")
}
}
控制HTTP headers和status
您可以控制响应的生成方式,HTTP status,headers,cookie等。
作为响应的一部分,您可以访问其内部上下文:
val call: ApplicationCall = response.call
val pipeline: ApplicationSendPipeline = response.pipeline
headers:
val headers: ResponseHeaders = response.headers
用于设置Set-Cookie标头的便捷cookie实例:
val cookies: ResponseCookies = response.cookies
获取和更改HTTP status:
response.status(HttpStatusCode.OK) - Sets the HttpStatusCode to a predefined standard one
response.status(HttpStatusCode(418, "I'm a tea pot")) - Sets the HttpStatusCode to a custom status code
val status: HttpStatusCode? = response.status() - Gets the currently set HttpStatusCode if set
response.contentType(ContentType.Text.Plain.withCharset(Charsets.UTF_8)) - Typed way for setting the Content-Type (for ContentType.Application.Json the default charset is UTF_8 without making it explicit)
response.contentType("application/json; charset=UTF-8") - Untyped way for setting the Content-Type header
自定义headers:
response.header("X-My-Header", "my value") - Appends a custom header
response.header("X-My-Times", 1000) - Appends a custom header
response.header("X-My-Times", 1000L) - Appends a custom header
response.header("X-My-Date", Instant.EPOCH) - Appends a custom header
设置标头的便捷方法:
response.etag("33a64df551425fcc55e4d42a148795d9f25f89d4") - Sets the ETag used for caching
response.lastModified(ZonedDateTime.now()) - Sets the Last-Modified header
response.contentLength(1024L) - Sets the Content-Length. This is generally automatically set when sending the payload
response.cacheControl(CacheControl.NoCache(CacheControl.Visibility.Private)) - Sets the Cache-Control header in a typed way
response.expires(LocalDateTime.now()) - Sets the Expires header
response.contentRange(1024L until 2048L, 4096L) - Sets the Content-Range header (check the PartialContent feature)
HTTP/2 Pushing和HTTP/1链接头
call支持Pushing功能。
- 在HTTP/2中,使用Pushing功能
- 在HTTP/1.2中,它将链接头添加为一个提示
routing {
get("/") {
call.push("/style.css")
}
}
注:Pushing减少了请求和页面显示之间的时间。但请注意,事先发送内容可能会发送已由客户端缓存的内容。
重定向
您可以使用respondRedirect方法轻松生成重定向响应,使用Location标头发送301 Moved Permanently或302 Found重定向。
call.respondRedirect("/moved/here", permanent = true)
发送响应内容
发送通用内容(与Content negotiation兼容):
call.respond(MyDataClass("hello", "world")) - Check the Content Negotiation section
call.respond(HttpStatusCode.NotFound, MyDataClass("hello", "world")) - Specifies a status code, and sends a payload in a single call. Check StatusPages
发送文本信息:
call.respondText("text") - Just a string with the body
call.respondText("p { background: red; }", contentType = ContentType.Text.CSS, status = HttpStatusCode.OK) { ... } - Sending a text specifying the ContentType, the HTTP Status and configuring the OutgoingContent
call.respondText { "string" } - Responding a string with a suspend provider
call.respondText(contentType = ..., status = ...) { "string" } - Responding a string with a suspend provider
call.respond(TextContent("{}", ContentType.Application.Json)) - Responding a string without adding a charset to the Content-Type
发送byte数组:
call.respondBytes(byteArrayOf(1, 2, 3)) - A ByteArray with a binary body
发送文件:
call.respondFile(File("/path/to/file")) - Sends a file
call.respondFile(File("basedir"), "filename") { ... } - Send a file and configures the OutgoingContent
发送URL编码的表单(application/x-www-form-urlencoded):
Use Parameters.formUrlEncode. Check the Utilities page for more information about this.
使用Writer发送分块内容:
call.respondWrite { write("hello"); write("world") } - Sends text using a writer. This is used with the HTML DSL
call.respondWrite(contentType = ..., status = ...) { write("hello"); write("world") } - Sends text using a writer and specifies a contentType and a status
使文件可下载
您可以通过添加Content-Disposition标头使文件“可下载”。以无类型的方式,您可以执行以下操作:
call.response.header(HttpHeaders.ContentDisposition, "attachment; filename=\"myfilename.bin\"")
但是Ktor还提供了一种带有正确转义的类型化方法来生成此标头:
call.response.header(HttpHeaders.ContentDisposition, ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, "myfilename.bin").toString())
Content negotiation(介绍)
在配置用于Content negotiation的插件时,管道可以接受call.respond方法的其他类型。
- 发送 HTML DSL
- 发送 HTMLFreeMarker
- 发送data class生成的json