Java字符编码,ISO到UTF转换

时间:2015-02-12 14:04:32

标签: java utf-8 character-encoding iso-8859-1 tibco-rv

这个主题已成为许多讨论的目标,但我们仍然看到新的主题出现。 我的方案如下:

在Linux服务器上运行的Java框架,其中UTF-8是JVM中的默认字符编码。该框架由一些接收要处理的Tibco RV消息的服务组成。其中一些消息包含非ASCII字符,并从Windows服务器发送,ISO8859-1是创建消息时使用的编码。 现在,当从Tib rv消息中提取数据时,有问题的字段“到达”作为Java对象并需要转换为字符串......而在这里我还没有能够提取包含非字符串的ISO8859-1字符串ASCII字符(瑞典语“å”,“ä”,“ö”)以正确的方式转换为UTF-8字符串。 我尝试过使用以下方法:

String isoStreet = new String(response.get("street").toString().getBytes(StandardCharsets.ISO_8859_1),java.nio.charset.StandardCharsets.UTF_8);

我也试过在java.nio包中使用编码器/解码器但没有成功。

有趣的是,我正在使用PuttY连接到服务所在且正在运行的服务器。从那里我有可能从shell发出一个直接的Tibco rv请求(使用tibcorvsend客户端),似乎我需要在登录之前在PuttY(Window_> Translation)中将远程字符集设置为ISO8859-1服务器并发出Tib rv请求 - 完成后,无论我在远程Linux服务器中设置了什么编码,这些非ASCII字符在响应中都显示正确。 使用'export LC_ALL = en_US.UTF-8'或'export LC_ALL = sv_SE.iso88591'在这种情况下无关紧要...只有我在PuttY中设置的远程编码......

Thsi应该暗示响应消息似乎没问题,并且至少shell能够输出正确的字符。但是当进入Java VM(使用Java服务)时,我想在Watch视图中调试和查看响应对象(不希望转换为字符串)时,响应字段会被静静地推送到字符串中...不确定是否可以关注我如果不是,我可能会在需要时尝试更清楚......

关于此问题的任何输入,任何人

此致 / R

1 个答案:

答案 0 :(得分:1)

A character encoding指定如何将包含字符的文本转换为字节,反之亦然。如您所知,有不同的字符编码,例如ASCII,ISO-8859-1和UTF-8。

字符串由字符组成。在某些时候,您希望将这些字符转换为字节,以便您可以通过网络发送它们,将它们存储在文件中或任何您想要执行的操作中。您使用字符编码将字符串转换为字节。另一方面,在接收字节的地方,您使用相同的字符编码将字节转换回字符串中的字符。

让我们来看看为什么像你发布的那条线不正确。让我们首先重写它,以便我可以解释这些部分:

String street = response.get("street").toString();
byte[] streetBytes = street.getBytes(StandardCharsets.ISO_8859_1);
String isoStreet = new String(streetBytes, StandardCharsets.UTF_8);

在第一行中,您从响应中获取一些数据并将其转换为字符串。 (response.get("street")返回什么?)。

在第二行中,使用ISO-8859-1字符集对该字符串进行编码。您将获得一个字节数组,其中包含字符串中字符的有效ISO-8859-1字符代码。

在第三行中,将字节转换为字符串,并假装字节为UTF-8字节。这显然是错误的,因为字节是ISO-8859-1数据而不是UTF-8数据。执行此操作时,如果字节数组包含根据UTF-8不是有效字符的字节序列,则可能会出现错误的字符,甚至是异常。

有一点需要注意的是,字符串只包含字符。字符串本身没有编码。您使用字符编码将字符串转换为字节,反之亦然。您不能“更改字符串的字符编码”,因为字符编码不是字符串的属性。就像数字本身不是十进制或十六进制一样 - 这些只是表示相同数字的不同方式。

你要做的是:

  • 在您编写邮件时,请确保使用正确的字符编码将字符串转换为字节。

  • 在您阅读邮件时,请确保使用正确的字符编码将字节转换为字符串。

不要使用平台的默认字符编码将某些内容读入字符串,然后尝试“转换字符串”。这不起作用。