Groovy-从UTF8字节创建的字符串有错误的字符



当得到一个web服务返回带有希腊字符的json的结果时出现了问题。实际上它是米科诺斯市。挑战在于,无论我使用什么编码或转换,它总是显示为:ΜΎίίxCE?¦Β∑。但它应该显示:

使用Powershell,我能够验证web服务是否返回了正确的字符。

当在Groovy中将字节数组转换为String时,我缩小了问题的范围。下面的代码重现了我的问题。myUTF8String保存我从URLConnection.content.text获得的字节数组。要查看的UTF8字节序列是0xce,0x9d。将其转换为字符串并返回字节数组后,该字符的字节序列为0xce,0x3f。下面代码的结果将显示原始字节数组的位置9与转换字符串的位置9的差异。对于下面的测试,我使用Groovy控制台4.0.6。

关于这个有什么线索吗?

import java.nio.charset.StandardCharsets;
def myUTF8String = "ce9cce8ece9ace9fce9dce9fcea3"
def bytes = myUTF8String.decodeHex();
content =  new String(bytes).getBytes()
for ( i = 0; i < content.length; i++ ) {
if ( bytes[i] != content[i] ) {
println "Different... at pos " + i
hex =  Long.toUnsignedString( bytes[i], 16).toUpperCase()
print hex.substring(hex.length()-2,hex.length()) + " != "
hex =  Long.toUnsignedString( content[i], 16).toUpperCase()
println hex.substring(hex.length()-2,hex.length())
}
}

非常感谢

Andreas

当从字节构建String时,必须指定字符集名称,否则将使用默认的java字符集,而不是urf-8。

Charset.defaultCharset((-返回此Java虚拟机的默认字符集。

String.getBytes((也有同样的问题-使用charset参数来获得正确的字节序列。

只需更改代码中的以下行,问题就会消失:

content =  new String(bytes, "UTF-8").getBytes("UTF-8")

作为一个选项,您可以使用以下命令行参数为整个JVM实例设置默认字符集:

java -Dfile.encoding=UTF-8 <your application>

但要小心,因为它会影响整个JVM实例!

https://docs.oracle.com/en/java/javase/19/intl/supported-encodings.html#GUID-DC83E43D-52F6-41D9-8F16-318F3F39D54F

最新更新