JavaPreparedStatement UTF-8字符问题

问题描述 投票:0回答:5

我有一份准备好的声明:

PreparedStatement st;

在我的代码中,我尝试使用 st.setString 方法。

st.setString(1, userName);

userName 的值为 şakça。 setString 方法将 'şakça' 更改为 '?akça'。它不识别 UTF-8 字符。我该如何解决这个问题?

谢谢。

java database jdbc utf-8 character-encoding
5个回答
42
投票

搞砸的方式实际上是相当多的。 如果您使用的是 MySQL,请尝试在 JDBC 连接 URL 末尾添加

characterEncoding=UTF-8
参数:

jdbc:mysql://server/database?characterEncoding=UTF-8

您还应该检查表/列字符集是否为 UTF-8。


7
投票

每当数据库将字符更改为

?
时,就意味着相关字符的代码点完全超出了表配置使用的字符编码范围。

至于问题的原因:

ç
位于ISO-8859-1范围内,并且具有与UTF-8U+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 中的
Ã
§
)。


3
投票

setString 方法将 'şakça' 更改为 '?akça'

你怎么知道 setString 改变了这个?还是你看到数据库中的内容并决定这样做?

可能是数据库未配置为 UTF-8,或者只是您用来查看数据库内容的工具(SQL*PLUS for Oracle...)无法显示 UTF-8。


0
投票

您可以使用如下查询在准备好的语句中设置unicode字符串。

PreparedStatement st= conn.prepareStatement("select * from users where username=unistr(?)");// unistr method is for oracle
    st.setString(1, userName);


0
投票

如果您正在使用 Servlet,则需要将此指令放入您正在使用的任何函数(processRequest、doGet 或 doPost)的开头:

request.setCharacterEncoding("UTF-8");
© www.soinside.com 2019 - 2024. All rights reserved.