4、Ktor学习-处理HTTP请求;

  处理路由或直接拦截管道时,您将获得ApplicationCall的上下文。 该调用包含一个名为request的属性,其中包含有关请求的信息。

介绍

  当使用路由功能或拦截请求时,您可以访问处理程序内的call属性。 该调用包括一个请求属性,其中包含有关请求的相关信息:

routing {
    get("/") {
        val uri = call.request.uri
        call.respondText("Request uri: $uri")
    } 
}

intercept(ApplicationCallPipeline.Call) { 
    if (call.request.uri == "/") {
        call.respondText("Test String")
    }
}
复制代码

请求信息

  作为请求的一部分,您可以访问其内部上下文:

val call: ApplicationCall = request.call
val pipeline: ApplicationReceivePipeline = request.pipeline
//URL, method, scheme, protocol, host, path, httpVersion, remoteHost, clientIp

val version: String = request.httpVersion // "HTTP/1.1"
val httpMethod: HttpMethod = request.httpMethod // GET, POST... 
val uri: String = request.uri // Short cut for `origin.uri`
val scheme: String = request.origin.scheme // "http" or "https"
val host: String? = request.host() // The host part without the port 
val port: Int = request.port() // Port of request
val path: String = request.path() // The uri without the query string
val document: String = request.document() // The last component after '/' of the uri
val remoteHost: String = request.origin.remoteHost // The IP address of the client doing the request
复制代码
反向代理支持:origin和local

  当在反向代理(例如nginx或负载均衡器)后面时,最终用户不会执行接收到的请求,而是反向代理。 这意味着连接的客户端IP地址将是代理而不是客户端之一。 反向代理也可能通过HTTPS提供服务并通过HTTP向您的服务器请求。 流行的反向代理发送X-Forwarded-标头以便能够访问此信息。

注:请注意,为了在反向代理下工作,您必须安装XForwardedHeaderSupport功能。

  作为请求对象的一部分,有两个属性local和origin,它们允许获取原始请求或本地/代理请求的信息。

val local : RequestConnectionPoint = request.local // Local information 
val origin: RequestConnectionPoint = request.origin // Local / Origin if XForwardedHeaderSupport feature is installed.
复制代码

  您可以获得的local/origin信息:

interface RequestConnectionPoint {
    val scheme: String // "http" or "https": The provided protocol (local) or `X-Forwarded-Proto`
    val version: String // "HTTP/1.1"
    val port: Int
    val host: String // The provided host (local) or `X-Forwarded-Host`
    val uri: String
    val method: HttpMethod
    val remoteHost: String // The client IP (the direct ip for `local`, or the redirected one `X-Forwarded-For`)
}
复制代码

GET/QUERY参数

  如果需要访问查询参数?param1 = value&param2 = value作为集合,则可以使用queryParameters。 它实现了StringValues接口,其中每个键都可以有一个与之关联的字符串列表。

val queryParameters: Parameters = request.queryParameters
val param1: String? = request.queryParameters["param1"] // To access a single parameter (first one if repeated)
val repeatedParam: List<String>? = request.queryParameters.getAll("repeatedParam") // Multiple values
复制代码

  您还可以访问原始queryString(param1 = value&param2 = value):

val queryString: String = request.queryString()
复制代码

POST, PUT 和 PATCH

  POST,PUT和PATCH请求具有关联的请求主体(有效负载)。

val channel: ByteReadChannel = call.receiveChannel()
val text: String = call.receiveText()
val inputStream: InputStream = call.receiveStream() // NOTE: InputStream is synchronous and blocks the thread
val multipart: MultiPartData = call.receiveMultipart()
复制代码
表单参数(urlencoded或multipart)

要解析urlencoded或multipart的表单,可以使用receiveParameters或receive <Parameters>:

val postParameters: Parameters = call.receiveParameters()
复制代码
接收类型对象,内容类型和JSON

该调用还支持接收通用对象:

val obj: T = call.receive<T>()
val obj: T? = call.receiveOrNull<T>()
复制代码

要从有效内容接收自定义对象,您必须使用ContentNegotiation功能。 例如,这对于在REST API中接收和发送JSON有效负载非常有用。

install(ContentNegotiation) {
    gson {
        setDateFormat(DateFormat.LONG)
        setPrettyPrinting()
    }
}
复制代码

如果将ContentNegotiation配置为使用gson,则需要包含ktor-gson工件:

compile("io.ktor:ktor-gson:$ktor_version")
复制代码

例子如下:

data class HelloWorld(val hello: String)

routing {
    post("/route") {
        val helloWorld = call.receive<HelloWorld>()
    }
}
复制代码

注:请记住,您的类必须在顶级(在任何其他类或函数之外)定义才能被Gson识别。

Cookies

  有一个cookie属性可以访问客户端发送的Cookie标头,就像它是一个集合一样:

val cookies: RequestCookies = request.cookies
val mycookie: String? = request.cookies["mycookie"]
复制代码

Headers

  要访问Headers,请求对象有一个标头:Headers属性。它实现了StringValues接口,其中每个键都可以有一个与之关联的字符串列表。

val headers: Headers = request.headers
val header: String? = request.header("HeaderName") // To access a single header (first one if repeated)
val repeatedHeader: List<String>? = request.headers.getAll("HeaderName") // Multiple values

//访问一些常见标头的几种便捷方法:
val contentType: ContentType = request.contentType() // Parsed Content-Tpe 
val contentCharset: Charset? = request.contentCharset() // Content-Type JVM charset
val authorization: String? = request.authorization() // Authorization header
val location: String? = request.location() // Location header
val accept: String? = request.accept() // Accept header
val acceptItems: List<HeaderValue> = request.acceptItems() // Parsed items of Accept header
val acceptEncoding: String? = request.acceptEncoding() // Accept-Encoding header
val acceptEncodingItems: List<HeaderValue> = request.acceptEncodingItems() // Parsed Accept-Encoding items 
val acceptLanguage: String? = request.acceptLanguage() // Accept-Language header
val acceptLanguageItems: List<HeaderValue> = request.acceptLanguageItems() // Parsed Accept-Language items
val acceptCharset: String? = request.acceptCharset() // Accept-Charset header
val acceptCharsetItems: List<HeaderValue> = request.acceptCharsetItems() // Parsed Accept-Charset items
val userAgent: String? = request.userAgent() // User-Agent header
val cacheControl: String? = request.cacheControl() // Cache-Control header
val ranges: RangesSpecifier? = request.ranges() // Parsed Ranges header

val isChunked: Boolean = request.isChunked() // Transfer-Encoding: chunked
val isMultipart: Boolean = request.isMultipart() // Content-Type matches Multipart
复制代码
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值