2016-07-26 26 views
1

我已经创建了一个Java程序(REST)服务。整个开发/测试是在Windows上完成的,现在部署到生产测试正在进行。然而,有“小”编码的问题出现了:Java字符串编码 - 与Windows不同的Linux

String s3 = new String("grün".getBytes(), "UTF-8"); 
logger.info(s3); 
logger.info("das ist wirklich grün"); 
logger.info(new String("das ist wirklich grün".getBytes("UTF-8"), "UTF-8")); 

我通过HTTP属性(Web应用程序托管在tomcat的,具有权威性的插件Apache的背后)我必须处理几个值接收。它们的编码方式与您在第1行中看到的一样。(此值显示在Windows和Linux上)。

当我把它转换为UTF-8就像在第1行并写入日志文件(log4j)我的Windows机器上有“grün”(这是正确的)。在Linux服务器上,我仍然有相同的输出。

然后我试着直接使用Umlaute(üäöetc),就像第2行一样,并且在Windows和Linux上这两个值都被正确写入日志文件。然后,我尝试像第3行那样进行一些转换,但结果相同:两个操作系统都显示相同的结果。

两台机器都具有相同的Java语言环境(Locale.getDefault()) - >我已经试过了。我无法改变将值插入到HTTP请求中的方式!

回答

1

两台机器都有相同的Java语言环境(Locale.getDefault()) - >我已经试过了。

这是默认字符集,而不是缺省语言环境,它决定了在解码/编码没有指定字符集的字符串时使用的字符集。

检查您的Windows和Linux计算机上返回的内容Charset.defaultCharset().name()。根据你所报告的症状,我预计他们会有所不同。

+0

是的,谢谢你,这暗示是在正确的方向。 Windows机器使用Windows-1252,而Linux使用UTF-8。 – karlis

+0

使用String s3 = new String(“grün”.getBytes(“windows-1252”),“UTF-8”);诀窍,现在它在Linux机器上也是正确的。然而,我并不是为什么我必须在Linux上使用windows charset,也许这个字符串最初是在Windows机器上创建的...... – karlis

+0

*“...也许该字符串最初是在Windows机器上创建的。”*可能是! –

1

像这样的东西是无效的:

String s3 = new String("grün".getBytes(), "UTF-8"); 

这里发生:您可以使用您在运行此系统的默认字符编码得到字节的字符串"grün"(因为你没有指定在getBytes()的调用中进行编码),然后将这些字节转换回String,指定这些字节为UTF-8编码的文本:

characters =>缺省字符编码中的字节(可能是也可能不是UTF -8)=>转换回字符,就好像字节是UT F-8编码文本

这显然只有在系统的默认字符编码是UTF-8时才能正常工作。在Windows上它不是(它可能是Windows-1252)。

字符串本身没有character encoding。没有“UTF-8字符串”或“将字符串从X转换为UTF-8”之类的东西。字符编码指定字符串中的字符如何转换为字节,反之亦然,但不是字符串本身的属性。您可以可以有一个字节数组,代表以特定字符编码编码的文本。 (就像“十进制”和“十六进制”不是数字本身的属性,只是如何表示数字)。

不要以这样的方式编写程序,它取决于它所运行的系统的默认字符编码;这意味着,例如,不要在String上调用getBytes(),而不指定字符编码(例如,如果未指定,则还有其他使用默认编码的API调用)。

+0

谢谢!你是对的,不应该这样使用。然而,在找到真正的问题和解决方案之后,改进总是可能的。 – karlis

+0

是的,所以解决方案是:检查程序中是否依赖默认字符编码的地方,并修复这些地方,使其不符合。 – Jesper

+0

这是我必须使用这样的东西的唯一部分。并感谢你的答案,现在它应该做它应该做的。 – karlis