KMM项目中Ktor特殊字符解析异常的解决方案咨询
解决Ktor解析含特殊字符API响应的问题
我之前也碰到过类似的Ktor字符解码异常问题,确实默认情况下Ktor的字符处理比较严格,遇到不符合指定编码的字符就会抛出MalformedInputException,而Gson因为默认开启了更宽松的容错策略所以能正常解析。下面几个方案你可以试试:
1. 自定义容错字符解码器
直接修改字符解码器的错误处理策略,把无效字符替换或者忽略掉,而不是抛出异常:
// 创建一个容错的UTF-8解码器 val tolerantUtf8Decoder = Charsets.UTF_8.newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) // 替换无效字符为默认替换符 .onUnmappableCharacter(CodingErrorAction.REPLACE) // 接收响应时使用这个解码器 val responseChannel = call.receive<ByteReadChannel>() val responseText = responseChannel.readText(tolerantUtf8Decoder) // 之后用responseText解析成你的数据类 val data = Json.decodeFromString<YourTargetModel>(responseText)
如果不想保留替换符,也可以把REPLACE改成IGNORE,直接跳过无效字符。
2. 手动处理字节数组再解析
先把响应转换成字节数组,再用容错方式转成字符串,之后再进行序列化解析:
val responseBytes = call.receive<ByteArray>() // 转成字符串时替换所有控制字符/无效字符 val cleanText = String(responseBytes, Charsets.UTF_8).replace(Regex("\\p{C}"), "") // 用Kotlinx Serialization解析 val data = Json.decodeFromString<YourTargetModel>(cleanText)
这个方法适合已经知道响应里的无效字符是个别情况,直接过滤掉不影响业务的场景。
3. 改用Gson作为Ktor的序列化器
既然Gson能正常解析这类响应,那可以直接在Ktor中配置Gson作为ContentNegotiation的序列化器,开启宽松模式:
首先确保你添加了Gson相关的Ktor依赖,然后在Application配置中:
install(ContentNegotiation) { gson { setLenient() // 开启宽松模式,允许解析非标准JSON或无效字符 serializeNulls() // 可选,根据你的需求配置 } }
之后直接用call.receive<YourTargetModel>()就能正常解析了,这个方案最省事,相当于复用Gson的容错能力。
为什么Ktor默认会抛异常?
Ktor默认使用的字符解码器是严格模式,当遇到无法匹配指定编码的字节序列时,就会抛出MalformedInputException;而Gson默认对字符解码和JSON语法都采用了更宽松的处理策略,所以能自动跳过或处理这类无效字符。
内容的提问来源于stack exchange,提问作者Md Hanif
相关产品推荐
相关产品推荐

