我有一份准备好的声明:
PreparedStatement st;
在我的代码中,我尝试使用 st.setString 方法。
st.setString(1, userName);
userName 的值为 şakça。 setString 方法将 'şakça' 更改为 '?akça'。它不识别 UTF-8 字符。我该如何解决这个问题?
谢谢。
搞砸的方式实际上是相当多的。 如果您使用的是 MySQL,请尝试在 JDBC 连接 URL 末尾添加
characterEncoding=UTF-8
参数:
jdbc:mysql://server/database?characterEncoding=UTF-8
您还应该检查表/列字符集是否为 UTF-8。
每当数据库将字符更改为
?
时,就意味着相关字符的代码点完全超出了表配置使用的字符编码范围。
至于问题的原因:
ç
位于ISO-8859-1范围内,并且具有与UTF-8(U+00E7)中完全相同的代码点。然而,ş
的UTF-8代码点完全超出了ISO-8859-1的范围(U+015F,而ISO-8859-1仅达到U+00FF)。数据库不会保留该字符并将其替换为 ?
。
因此,我怀疑您的数据库表仍配置为使用 ISO-8859-1(或在其他兼容的 ISO-8859 编码之一中,其中
ç
具有与 UTF-8 中相同的代码点)。
Java/JDBC API 在字符编码方面做得非常好(Java 一直使用 Unicode),并且 JDBC DB 连接编码也配置正确。如果 Java/JDBC 错误地使用了 ISO-8859-1,则持久化结果将是
Åakça
(ş
存在字节 0xC5
和 0x9F
,分别代表 ISO 中的 Å
和 a
) -8859-1 和 ç
存在字节 0xC3
和 0xA7
代表
ISO-8859-1 中的 Ã
和 §
)。
setString 方法将 'şakça' 更改为 '?akça'
你怎么知道 setString 改变了这个?还是你看到数据库中的内容并决定这样做?
可能是数据库未配置为 UTF-8,或者只是您用来查看数据库内容的工具(SQL*PLUS for Oracle...)无法显示 UTF-8。
您可以使用如下查询在准备好的语句中设置unicode字符串。
PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr method is for oracle
st.setString(1, userName);
如果您正在使用 Servlet,则需要将此指令放入您正在使用的任何函数(processRequest、doGet 或 doPost)的开头:
request.setCharacterEncoding("UTF-8");