标签: ktor

找不到类“...”的序列化程序。将类标记为 @Serializable 或显式提供序列化器

您好,我在 kotlin 中类序列化时遇到问题

构建.gradl.kt

...
plugins {
    application
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.serialization").version("1.6.21")
}
...
depenedancies{
...
    implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
} 
Run Code Online (Sandbox Code Playgroud)

响应.kt

import kotlinx.serialization.*
...
interface BaseResponse<T>

@Serializable
data class PaginatedResponse<T>(
    val prev: Int?,
    val next: Int?,
    val totalCount: Int = 0,
    val totalPages: Int = 0,
    val data: T? = null,
    val message: String? = null
) : BaseResponse<T>
Run Code Online (Sandbox Code Playgroud)

用法

...
  return PaginatedResponse<List<User>>(
                prev,
                next,
                totalCount,
                totalPages,
                users
            )
Run Code Online (Sandbox Code Playgroud)

我传递的数据看起来很健康 在此输入图像描述 接下来是返回时抛出的错误

kotlinx.serialization.SerializationException: Serializer for class 'PaginatedResponse' is not found.
Mark the …
Run Code Online (Sandbox Code Playgroud)

kotlin ktor kotlinx.serialization

36
推荐指数
1
解决办法
3万
查看次数

处理 HttpClient Ktor 中的异常

我在公共模块中编写了如下公共代码,并在JS环境中进行了测试

val response = client.post<HttpResponse>(url) {
    body = TextContent("""{"a":1,"b":2}""", ContentType.Application.Json)
}
if (response.status != HttpStatusCode.OK) {
    logger.error("Error, this one failed bad?")
}

Run Code Online (Sandbox Code Playgroud)

但我的代码以 client.post 结尾,在没有网络的情况下出现取消的 corutineException 。我该如何处理这个异常以及任何其他异常?如果有互联网连接。没有任何失败,我希望能够处理异常。如何?

注意:try、catch 不起作用

kotlin ktor kotlin-multiplatform

20
推荐指数
3
解决办法
2万
查看次数

java.lang.UnsupportedOperationException: 反射 setAccessible(true) 已禁用

当我运行我的 Ktor 应用程序时,gradle run我遇到了以下异常:

19:21:11.795 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
19:21:11.810 [main] DEBUG io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
19:21:11.810 [main] DEBUG io.netty.util.internal.PlatformDependent0 - Java version: 11
19:21:11.811 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
19:21:11.812 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
19:21:11.812 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
19:21:11.814 [main] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: unavailable
java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled
        at io.netty.util.internal.ReflectionUtil.trySetAccessible(ReflectionUtil.java:31)
        at io.netty.util.internal.PlatformDependent0$4.run(PlatformDependent0.java:225)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:219)
        at io.netty.util.internal.PlatformDependent.isAndroid(PlatformDependent.java:273)
        at io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:92) …
Run Code Online (Sandbox Code Playgroud)

java netty kotlin ktor

19
推荐指数
1
解决办法
3万
查看次数

withTimeout 函数给出了 IllegalStateException:没有事件循环。使用 runBlocking { ... } 启动一个。在 Kotlin 多平台 iOS 客户端中

更新:如果我首先在没有超时的情况下执行协程然后使用超时,它会起作用。但是如果我先执行一个协程 withTimeout 那么它会给我一个错误。异步也是如此。

我正在创建一个演示 kotlin 多平台应用程序,我在其中使用 ktor 执行 API 调用。我想在 ktor 请求上有一个可配置的超时函数,所以我在协程级别使用 withTimeout 。

这是我使用网络 API 调用的函数。

suspend fun <T> onNetworkWithTimeOut(
    url: String,
    timeoutInMillis: Long,
    block: suspend CoroutineScope.() -> Any): T {
    return withTimeout(timeoutInMillis) {
        withContext(dispatchers.io, block)
    } as T
}

suspend fun <T> onNetworkWithoutTimeOut(url: String, block: suspend CoroutineScope.() -> Any): T {
    return withContext(dispatchers.io, block) as T
}
Run Code Online (Sandbox Code Playgroud)

这是我的 iOSMain 模块的 AppDispatcher 类。

@InternalCoroutinesApi
actual class AppDispatchersImpl : AppDispatchers {
@SharedImmutable
override val main: CoroutineDispatcher =
    NsQueueDispatcher(dispatch_get_main_queue())

@SharedImmutable
override …
Run Code Online (Sandbox Code Playgroud)

ios kotlin ktor kotlin-native kotlin-coroutines

18
推荐指数
1
解决办法
1914
查看次数

使用 Ktor 时出现“未找到转换:类 io.ktor.utils.io.ByteChannelNative”错误

我正在尝试获取并反序列化github上托管的一些数据。

{
  "Meals": [
    {
      "id": "1598044e-5259-11e9-8647-d663bd870b02",
      "name": "Tomato pasta",
      "quantity": [{
        "quantity": 1 },
        {
          "quantity": 2
        },
        {
          "quantity": 3
        }],
      "availableFromDate": "1605802429",
      "expiryDate": "1905802429",
      "info": "Vegetarian",
      "hot": false,
      "locationLat": 57.508865,
      "locationLong": -6.292,
      "distance": null
    },
    {
      "id": "2be2d854-a067-43ec-a488-2e69f0f2a624",
      "name": "Pizza",
      "quantity": [{
        "quantity": 1 },
        {
        "quantity": 2
        },
        {
          "quantity": 3
        }
      ],
      "availableFromDate": "1605802429",
      "expiryDate": "1905902429",
      "info": "Meat",
      "hot": false,
      "locationLat": 51.509465,
      "locationLong": -0.135392,
      "distance": null
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

如果我在本地启动json 服务器,那么它会完美工作,所以我知道我的数据类不是问题。但是,当我尝试从 github …

json kotlin ktor kotlin-multiplatform

16
推荐指数
3
解决办法
2万
查看次数

在 Ktor 客户端中重新触发 loadTokens 的正确方法

在我的移动应用程序中,我有一个单例 Ktor HttpClient,其不记名身份验证配置如下:

\n
HttpClient(\xe2\x80\xa6) {\n    install(Auth) {\n        bearer {\n            sendWithoutRequest { requestBuilder -> some condition }\n            loadTokens(tokensStorage::getTokens)\n            refreshTokens {\n                performTokenRefresh(oldTokens.refreshToken)\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在考虑以下流程:

\n
    \n
  1. 用户打开应用程序,而 my 中存储的令牌tokenStorage无效。
  2. \n
  3. 从中加载HttpClient令牌tokenStorage,请求失败并返回 401。
  4. \n
  5. 尝试HttpClient执行刷新,但也失败,因为刷新令牌无效。
  6. \n
  7. 用户被重定向到登录页面,登录,新的有效令牌存储在tokenStorage.
  8. \n
  9. 现在,用户可以从应用程序重试第 2-3 点中失败的呼叫。然而,这将永远失败,直到应用程序关闭,因为它HttpClient不再尝试调用loadTokens。确实,从源代码来看,loadTokens只被调用一次,然后就不会再被调用。
  10. \n
\n

我找到了解决该问题的几种方法。

\n

第一个是手动BearerAuthProviderHttpClient自己清除令牌,如以下代码片段所示,但这似乎是一种黑客解决方法:

\n
httpClient.plugin(Auth).providers\n    .filterIsInstance<BearerAuthProvider>()\n    .first().clearToken()\n
Run Code Online (Sandbox Code Playgroud)\n

tokenStorage另一种方法是从 my in手动加载当前令牌refreshToken并忽略传入的内容this@refreshTokens.oldTokens …

kotlin ktor ktor-client

14
推荐指数
0
解决办法
1521
查看次数

Ktor 客户端的 JsonFeature 未解决

我正在 android 中启动基于 Ktor 的客户端,我想使用任何序列化器,目前是来自 kotlinx 的序列化器,但结果与其他序列化器相同 - 未找到 JsonFeature(在下面的代码片段中突出显示)。我缺少什么?

class StreamClient {
    val client: HttpClient
    init {
        client = HttpClient(Android) {
            install(JsonFeature) {
                serializer = KotlinxSerializer()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

摇篮:

implementation("io.ktor:ktor-client-core:$ktor_version")
implementation("io.ktor:ktor-client-android:$ktor_version")
implementation("io.ktor:ktor-client-serialization:$ktor_version")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0")
Run Code Online (Sandbox Code Playgroud)

android json kotlin ktor

13
推荐指数
3
解决办法
1万
查看次数

Kotlinx 序列化 MissingFieldException

我正在使用 Ktor 从 Moshi 转换为 kotlinx 序列化,当我尝试请求获取数据时,我收到此错误

kotlinx.serialization.MissingFieldException: 字段 'attachments' 是必需的,但它丢失了

这是有道理的,因为此特定响应不包含此字段

响应JSON

{
    "data": {
        "id": "1299418846990921728",
        "text": "This is a test"
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我的 Serialized 类将该attachments字段设为可空(它仅在需要时才在响应中)所以它应该忽略它我想就像它对 Moshi 所做的那样

@Serializable
data class ResponseData(
    val id: Long
    val attachments: Attachments?,
    val author_id: String?,
    val text: String
}
Run Code Online (Sandbox Code Playgroud)

在我的 Ktor 客户端设置中,我将其设置为忽略未知密钥

private val _client: HttpClient = HttpClient(engine) {
    install(JsonFeature) {
        val json = Json {
            this.isLenient = true
            this.ignoreUnknownKeys = true
        }
        serializer = KotlinxSerializer(json)
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么它仍然说该字段是必需的,即使它可以为空?

ktor kotlinx.serialization

12
推荐指数
2
解决办法
2383
查看次数

如何在IntelliJ中设置'-Xuse-experimental = kotlin.experimental'

尝试在IntelliJ中构建Kotlin / Ktor应用程序时,出现以下形式的多个警告

Warning:(276, 6) Kotlin: This class can only be used with the compiler argument '-Xuse-experimental=kotlin.Experimental'
Run Code Online (Sandbox Code Playgroud)

输出。警告是指

@UseExperimental(KtorExperimentalLocationsAPI::class)
Run Code Online (Sandbox Code Playgroud)

所以预期通过设定以满足警告设置- >构建- >编译器- >科特林编译器- >附加的命令行参数-version -Xuse-实验= kotlin.Experimental。(-version已经在那里)。但是仍会生成警告。我如何满足呢?谢谢您的期待。

intellij-idea compiler-warnings kotlin ktor

11
推荐指数
3
解决办法
1594
查看次数

使用 openapi-generator 生成 ktor 服务器存根的正确方法是什么

当尝试从 openapi 为 ktor 生成服务器端存根时,对我来说输出看起来并不是很实用。

在 Github 上设置了一个示例项目,可以在其中查看设置。因为我需要在我的实际项目中使用 maven,所以我在这里也使用了它,但我想这对其他生成方法应该没有影响。

POM 的相关部分是这样的:

<build>
    ...

    <plugins>
        ...

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <executions>
                <execution>
                    <id>resources</id>
                    <phase>compile</phase>
                    <goals><goal>copy-resources</goal></goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/resources</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

将生成的内容如下:

  • 数据模型
  • Paths.kt包含 ktor-locations 格式的路径路径的对象
  • 将 API 作为扩展函数实现的示例存根 io.ktor.routing.Route
  • 一个完整的应用程序,包括 configs、Dockerfile、Gradle Files 等。

来自 SpringBoot 和 Swagger,我有点困惑,因为如果您想创建一个实现真正业务逻辑的实际应用程序,这组文件并不是很有用。我本来希望一些默认实现包含我只需要实现/覆盖的单个方法。我意识到 ktor 没有内置 DI,所以我也希望必须以routing某种方式扩展我的应用程序中的存根。

但是,有了这组生成的代码,我真的只能使用数据模型和Paths.kt对象。我将拥有自己的应用程序和默认实现,我无法覆盖但需要自己完全重写。

所以我的问题是,如何设置一个合适的 ktor 应用程序实现 openapi 规范。我是否错过了什么,或者我真的只得到模型并Paths.kt与之合作?

编辑

为了更清楚:特别是对于我的应用程序的这些部分,我不高兴没有工具的支持:

fun Application.module(testing: Boolean = false) { …
Run Code Online (Sandbox Code Playgroud)

maven kotlin ktor openapi-generator

10
推荐指数
0
解决办法
1386
查看次数