Как передать данные между различными частями трубопровода в Ктор (Котлин)

Я строю API и использую intercept(ApplicationCallPipeline.Call){} запустить некоторую логику перед каждым выполнением маршрута. Мне нужно передать данные из метода intercept() в вызываемый маршрут, и я устанавливаю данные с помощью call.attributes.put() в перехват (), как это:

val userKey= AttributeKey<User>("userK") call.attributes.put(userKey, userData)

И получить userData с call.attributes[userKey], Что происходит то call.attributes[userKey] работает только в методе intercept(), где я установил атрибут. Это не работает на маршруте, где мне это нужно. Это меня бросает java.lang.IllegalStateException: No instance for key AttributeKey: userK

Интересно, правильно ли я все делаю

1 ответ

Решение

Вот самый простой код, воспроизводящий то, что вы описываете:

class KtorTest {

    data class User(val name: String)

    private val userKey = AttributeKey<User>("userK")
    private val expected = "expected name"

    private val module = fun Application.() {
        install(Routing) {
            intercept(ApplicationCallPipeline.Call) {
                println("intercept")
                call.attributes.put(userKey, User(expected))
            }

            get {
                println("call")
                val user = call.attributes[userKey]
                call.respond(user.name)
            }

        }
    }

    @Test fun `pass data`() {
        withTestApplication(module) {
            handleRequest {}.response.content.shouldNotBeNull() shouldBeEqualTo expected
        }
    }

}

Я перехватываю вызов, помещаю пользователя в атрибуты и, наконец, отвечаю пользователю в запросе get. Тест проходит.

Какую версию ktor вы используете и какой движок?

Другие вопросы по тегам