Read/Write 双字节字符来自 java 托管在 WAS8.5.5 上的应用程序
Read/Write Double byte chars from java application hosted on WAS8.5.5
目前我们的应用程序托管在 WAS6.1 上,符合 Java 1.5。此应用程序能够 read/write 双字节(日语)字符 from/to 数据库(Sql Server 2008)。我使用 Java 1.7 重新编译了相同的代码并部署在 WAS8.5.5 服务器上。但是从 WAS8.5.5 托管应用程序中,每当我读取双字节字符并存储在数据库中时,这些字符都存储为 ???。我猜想 WAS8.5.5 应用程序无法将这些字符作为 UTF-8 进行处理。 JVM 上是否有任何设置可以更改为将所有 .class 文件读取为 UTF-8?两个服务器都有相同的代码。感谢任何帮助。
Java 字符串在内部采用 UTF-16 编码,因此当您从数据库读取字符串时,JDBC 驱动程序负责将任何数据库内部格式反序列化为 java 字符串.
无法设置编译器来防止这种情况发生。此外,虽然 .java 源可以用不同的方式编码,但 class 文件中的字节码并非如此。
我会调查 JDBC 驱动程序(不太可能)或 HTTP 传输。
如果你想做一个测试,尝试从数据库中读取一个值,然后在不通过请求/响应序列化/反序列化的情况下再次将它写入数据库,如果它保持为真,那么你找到了罪魁祸首。
大多数情况下,问题来自于解释传入流或使用错误的默认值写入传出流。
查看 IBM KB 了解更多信息。
编辑
我验证了你的例子,令我惊讶的是改变源编码确实改变了结果输出。
所以我尝试从 cmd 行调用它,将控制台设置为 utf-8 (chcp 65001
),经过几次检查后,当您更改 java 来源,Eclipse 在 运行 应用程序时更改默认编码。
我通过编译后的 class.
的 md5sum 再次检查了 class 文件
所以您在控制台上得到的肯定是 file.encoding 属性 在您的测试应用程序 运行 中使用的结果。
我仍然认为您应该检查请求输入和结果输出的编码,因为它们在很大程度上取决于容器,并且更改 websphere 版本可能会导致某些配置中的默认值不同,而且仅更改容器实例也会重置配置完成(必须重新应用)。
我解决了这个问题。但是更新这个线程,认为这可能对某人有所帮助。
问题出在 JDBC 驱动程序上。 SQL 服务器驱动程序在 WAS 6.1.1 中的工作方式与在 WAS 8.5.5 中的工作方式不同。当我在 WAS 8.5.5 中创建一个新的数据源时,我得到了一些默认的自定义属性。自定义 属性 "sendStringParametersAsUnicode" 值之一设置为 false。期望值是真实的。一旦我更改为 true,我就可以正确地将双字节字符写入数据库。
目前我们的应用程序托管在 WAS6.1 上,符合 Java 1.5。此应用程序能够 read/write 双字节(日语)字符 from/to 数据库(Sql Server 2008)。我使用 Java 1.7 重新编译了相同的代码并部署在 WAS8.5.5 服务器上。但是从 WAS8.5.5 托管应用程序中,每当我读取双字节字符并存储在数据库中时,这些字符都存储为 ???。我猜想 WAS8.5.5 应用程序无法将这些字符作为 UTF-8 进行处理。 JVM 上是否有任何设置可以更改为将所有 .class 文件读取为 UTF-8?两个服务器都有相同的代码。感谢任何帮助。
Java 字符串在内部采用 UTF-16 编码,因此当您从数据库读取字符串时,JDBC 驱动程序负责将任何数据库内部格式反序列化为 java 字符串.
无法设置编译器来防止这种情况发生。此外,虽然 .java 源可以用不同的方式编码,但 class 文件中的字节码并非如此。
我会调查 JDBC 驱动程序(不太可能)或 HTTP 传输。
如果你想做一个测试,尝试从数据库中读取一个值,然后在不通过请求/响应序列化/反序列化的情况下再次将它写入数据库,如果它保持为真,那么你找到了罪魁祸首。
大多数情况下,问题来自于解释传入流或使用错误的默认值写入传出流。
查看 IBM KB 了解更多信息。
编辑
我验证了你的例子,令我惊讶的是改变源编码确实改变了结果输出。
所以我尝试从 cmd 行调用它,将控制台设置为 utf-8 (chcp 65001
),经过几次检查后,当您更改 java 来源,Eclipse 在 运行 应用程序时更改默认编码。
我通过编译后的 class.
的 md5sum 再次检查了 class 文件所以您在控制台上得到的肯定是 file.encoding 属性 在您的测试应用程序 运行 中使用的结果。
我仍然认为您应该检查请求输入和结果输出的编码,因为它们在很大程度上取决于容器,并且更改 websphere 版本可能会导致某些配置中的默认值不同,而且仅更改容器实例也会重置配置完成(必须重新应用)。
我解决了这个问题。但是更新这个线程,认为这可能对某人有所帮助。 问题出在 JDBC 驱动程序上。 SQL 服务器驱动程序在 WAS 6.1.1 中的工作方式与在 WAS 8.5.5 中的工作方式不同。当我在 WAS 8.5.5 中创建一个新的数据源时,我得到了一些默认的自定义属性。自定义 属性 "sendStringParametersAsUnicode" 值之一设置为 false。期望值是真实的。一旦我更改为 true,我就可以正确地将双字节字符写入数据库。