Interception per route

预计阅读时间:2分钟

如果只想截取特定路由的某些呼叫,则必须创建一个Route节点(通常通过调用createChild )并截取该节点.

例如,要为路由创建超时,可以执行以下操作:

fun Route.routeTimeout(time: Long, unit: TimeUnit = TimeUnit.SECONDS, callback: Route.() -> Unit): Route {
    // With createChild, we create a child node for this received Route  
    val routeWithTimeout = this.createChild(object : RouteSelector(1.0) {
        override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation =
            RouteSelectorEvaluation.Constant
    })

    // Intercepts calls from this route at the features step
    routeWithTimeout.intercept(ApplicationCallPipeline.Features) {
        withTimeout(time, unit) {
            proceed() // With proceed we can define code to be executed before and after the call
        }
    }
    
    // Configure this route with the block provided by the user
    callback(routeWithTimeout)

    return routeWithTimeout
}

Intercepting any Route node

Route类定义了适用于该路由节点或任何其他内部路由的拦截方法:

/// Installs an interceptor into this route which will be called when this or a child route is selected for a call
fun Route.intercept(phase: PipelinePhase, block: PipelineInterceptor<Unit, ApplicationCall>)

Getting the route being handled

您可以通过将call: ApplicationCall RoutingApplicationCall为具有route: Route属性的RoutingApplicationCall来获取正在处理的route: Route .

Getting the route path

Route重写toString()方法以生成到该路径的路径,例如:

override fun Route.toString() = when {
    parent == null -> "/"
    parent.parent == null -> "/$selector"
    else -> "$parent/$selector"
}

How to intercept preventing additional executions

    intercept(ApplicationCallPipeline.Setup) {
        if (call.request.path() == "/admin/book") {
            call.respondText {
                "intercept book"
            }
            // Truncate the route response. If there is no finish() function,
            // the route /book will still respond to the processing, and the pipeline will be unwritable.
            return@intercept finish()
        } 
    }

Hooking before and after routing

您可以使用事件Routing.RoutingCallStartedRouting.RoutingCallFinished来全局拦截路由呼叫:

pipeline.environment.monitor.subscribe(Routing.RoutingCallStarted) { call: RoutingApplicationCall ->
    println("Route started: ${call.route}")
}

pipeline.environment.monitor.subscribe(Routing.RoutingCallFinished) { call: RoutingApplicationCall ->
    println("Route completed: ${call.route}")
}

您可以在" 度量标准"功能中看到完整的示例.

by  ICOPY.SITE