java.lang.IllegalStateException: 序列化正文失败。内容类型:class java.util.Collections$SingletonList
java.lang.IllegalStateException: Fail to serialize body. Content has type: class java.util.Collections$SingletonList
我正在尝试将 JSON 字符串列表反序列化到 ktor POST 测试请求的正文中。
但是我收到以下错误:
java.lang.IllegalStateException: Fail to serialize body. Content has type: class java.util.Collections$SingletonList, but OutgoingContent expected.
If you expect serialized body, please check that you have installed the corresponding feature(like `Json`) and set `Content-Type` header.)
有什么建议吗?
这是我的测试设置:
import io.ktor.client.HttpClient
import io.ktor.client.engine.mock.MockEngine
import javax.inject.Singleton
@Provides
@Singleton
fun provideKtorHttpClient(
mockEngine: MockEngine
): HttpClient {
return HttpClient(mockEngine) {
install(JsonFeature) {
serializer = KotlinxSerializer()
acceptContentTypes = listOf(
ContentType.parse("application/vnd.any.response+json"),
ContentType.parse("application/json")
)
}
}
}
@Provides
@Singleton
fun mockEngine(): MockEngine {
val mockEngine = MockEngine { request ->
when {
request.url.fullPath.endsWith("lorem") -> {
val body = request.body as TextContent
val words: List<String> = Json.decodeFromString(body.text)
when (words[0]) {
"Foo" -> respond(
content = ByteReadChannel("Ok"),
status = HttpStatusCode.OK,
headers = headersOf(HttpHeaders.ContentType, "application/json")
)
else ->
respond(
content = ByteReadChannel("Not found"),
status = HttpStatusCode.NotFound,
headers = headersOf(HttpHeaders.ContentType, "application/json")
)
}
}
}
}
}
class MyApi @Inject constructor(
private val httpClient: HttpClient
) {
suspend fun postData(words: List<String>): Either<Exception, String> = Either.catch {
httpClient.post<String>("https://foo.bar/api/lorem") {
body = words
}
}
}
@Test
fun testApiOk() = runBlocking {
val myApi = MyApi(httpClient, networkingConstants)
runBlocking {
val result = myApi.postData(listOf("Foo"))
assertTrue(result.isRight())
}
}
只需将 Content-Type
header 添加到请求生成器,这样 JsonFeature
就会序列化 body。
suspend fun postData(words: List<String>): Either<Exception, String> = Either.catch {
httpClient.post<String>("https://foo.bar/api/lorem") {
body = words
contentType(ContentType.Application.Json)
}
}
我正在尝试将 JSON 字符串列表反序列化到 ktor POST 测试请求的正文中。 但是我收到以下错误:
java.lang.IllegalStateException: Fail to serialize body. Content has type: class java.util.Collections$SingletonList, but OutgoingContent expected.
If you expect serialized body, please check that you have installed the corresponding feature(like `Json`) and set `Content-Type` header.)
有什么建议吗?
这是我的测试设置:
import io.ktor.client.HttpClient
import io.ktor.client.engine.mock.MockEngine
import javax.inject.Singleton
@Provides
@Singleton
fun provideKtorHttpClient(
mockEngine: MockEngine
): HttpClient {
return HttpClient(mockEngine) {
install(JsonFeature) {
serializer = KotlinxSerializer()
acceptContentTypes = listOf(
ContentType.parse("application/vnd.any.response+json"),
ContentType.parse("application/json")
)
}
}
}
@Provides
@Singleton
fun mockEngine(): MockEngine {
val mockEngine = MockEngine { request ->
when {
request.url.fullPath.endsWith("lorem") -> {
val body = request.body as TextContent
val words: List<String> = Json.decodeFromString(body.text)
when (words[0]) {
"Foo" -> respond(
content = ByteReadChannel("Ok"),
status = HttpStatusCode.OK,
headers = headersOf(HttpHeaders.ContentType, "application/json")
)
else ->
respond(
content = ByteReadChannel("Not found"),
status = HttpStatusCode.NotFound,
headers = headersOf(HttpHeaders.ContentType, "application/json")
)
}
}
}
}
}
class MyApi @Inject constructor(
private val httpClient: HttpClient
) {
suspend fun postData(words: List<String>): Either<Exception, String> = Either.catch {
httpClient.post<String>("https://foo.bar/api/lorem") {
body = words
}
}
}
@Test
fun testApiOk() = runBlocking {
val myApi = MyApi(httpClient, networkingConstants)
runBlocking {
val result = myApi.postData(listOf("Foo"))
assertTrue(result.isRight())
}
}
只需将 Content-Type
header 添加到请求生成器,这样 JsonFeature
就会序列化 body。
suspend fun postData(words: List<String>): Either<Exception, String> = Either.catch {
httpClient.post<String>("https://foo.bar/api/lorem") {
body = words
contentType(ContentType.Application.Json)
}
}