Scala API特殊字符编码异常导致Python客户端报错的服务端修复问询
Scala服务端字符处理异常修复方案
问题根因
- 字节数组转字符串逻辑错误:现有代码
value.map(_.toChar).mkString直接将每个单字节映射为Unicode字符,仅适配ASCII编码内容。’这类特殊字符的UTF-8编码占3个字节,拆分单个字节转Char会生成多个孤立非法字符,大部分会被判定为控制字符,进而被替换为�。 - 响应编码未明确声明:服务端返回响应时没有指定UTF-8编码标识,Python客户端默认使用ASCII解码,碰到
�这类超出ASCII范围的字符直接抛出UnicodeEncodeError。
修复步骤
1. 修正字节数组转字符串的逻辑
按照原始字节的编码格式(默认使用UTF-8即可)解码为字符串,不要逐字节强制转Char,修正后代码如下:
import io.circe._, io.circe.generic.auto._, io.circe.syntax._, io.circe.parser._, io.circe.optics.JsonPath._ import java.nio.charset.StandardCharsets private def bytesToJsonCirce(value: Array[Byte]): Json = { // 按UTF-8正确解码字节数组后再做控制字符过滤 val rawStr = new String(value, StandardCharsets.UTF_8) parse(encodeCharacters(rawStr)) match { case Right(x: Json) => x case Left(err: ParsingFailure) => logger.error(err.getLocalizedMessage) Json.Null } } private def encodeCharacters(x: String): String = { val encodeChar = '�' (x.toCharArray map { case y if y.isControl => encodeChar case y => y }).mkString }
如果原始字节数组采用的是非UTF-8编码,替换StandardCharsets.UTF_8为对应编码即可。
2. 明确接口响应的编码声明
在服务端返回API响应时,设置Content-Type头为application/json; charset=utf-8,主动告知客户端返回内容为UTF-8编码,Python客户端就会默认采用UTF-8解码,无需额外手动调用编码方法也不会触发ASCII编码错误。
验证效果
修复后原始文本He shouldn’t be allowed会被完整保留,不会被替换为�,客户端直接读取响应内容也不会抛出编码异常。
内容的提问来源于stack exchange,提问作者curiousguy
相关产品推荐
相关产品推荐

