我的属性文件中有一个拉丁文1字符:
Privé vervoer
使用UTF-8存储属性文件。这导致了问题,并且以乱码的方式返回到UI(单独的js应用程序)。
我理解为什么会这样。默认情况下,属性文件被视为ISO-8859-1。因此,正如通常所建议的那样,我将é更改为其Unicode转义表示 - \ u00E9。
现在,一切都像魅力一样,但我仍然感到困惑。 Java会将此char视为ISO-8859-1编码。这很酷。但是当这个相同的String返回到UI时,它应该是UTF-8编码的,因为这是UI期望的(Content-Type: "application/json; charset=utf-8"
和charset="utf-8"
元标记)。
我仍然无法理解从ISO-8859-1到UTF-8的转换何时发生。
如果字符是Unicode转义,是否需要它?也许基于底层应用程序/操作系统可以正确显示转义字符?
我的堆栈:Mule ESB,Java 8,Spring 4,基于Angular的UI和中间的nodejs网关。
答案 0 :(得分:1)
字符编码包括将字符转换为字节序列。当您写入文件或网络时,这是必要的。
类似地,当您从文件或网络中读取字符时,实际上是读取字节,并且字节序列被解码为字符。
Properties类在从文件读取时,期望该文件包含ISO_8859_1编码的字符,即通过使用ISO_8859_1编码字符获得的字节。因此,它从文件中读取字节,使用ISO_8859_1对它们进行解码,并将它们存储为字符串的键值对(包含字符)。
当您将这些字符写入网络时,这些字符会再次转换为字节,您当然不会被迫使用与用于属性文件的编码相同的编码。因此,如果您愿意,可以选择UTF_8。
ISO_8859_1是属性文件的一个愚蠢(IMO)选择,特别是考虑到它们用于资源包,包含以多种语言翻译的消息。实际上,ISO_8859_1仅支持256个字符(不是所有可打印的),而不是整个Unicode集。 UTF-8本来是一个更好的选择。 ISO_8859_1支持您的特定字符(é
),因此您实际上无需转义它。但是,如果您在文件中存储了西里尔文,阿拉伯文或其他类型的非文字字符,那么您将不得不将这些字符转换为\uxxxx
个字符序列(它们本身只包含可以使用ISO_8859_1编码的字符:{{ 1}},\
和数字)