Java 中的 UTF-8 字符在 MySQL 中变为无效字符
UTF-8 Character in Java becomes Invalid Character in MySQL
具有来自外部 REST / JSON 数据源的值作为特殊字符。我使用预先存在的实用程序 CharDecoder.java 对其进行转换,它保持不变,但在将其插入 MySQL 数据库(默认字符集为 UTF-8)后,它从 ć 变为 ?.
我的程序流程是这样的:
外部数据源发送 JSON --> CharDecoder(在 tomcat7 中的 war 文件中,处理特殊字符)然后填充一行 --> 在 MySQL 数据库中。
MySQL 数据库中的最终结果是无效字符。
开发环境信息:
我正在使用 Java 1.7.
Maven 3.3.3,在我的 pom.xml 的 <properties>
标签中:
< project.build.sourceEncoding > UTF-8 < /project.build.sourceEncoding >
MacOS 上的 Eclipse Oxygen。
在 macOS 上 运行ning Eclipse Oxygen - 在项目的属性视图中(单击项目和 ⌘I 也称为 COMMAND+I),它指出文本文件编码为 UTF-8。
当我使用代码库中的实用程序 class 转换它时,它可以工作,但是当更新 MySQL 数据库中的行时(table 的默认字符集是UTF-8) 它变成了一个无效的字符。
所以,我将这个字符添加到我的字符数组中:“ć”(它位于以“î”开头的同一行)。
public class CharDecoder {
public final static String chars [] =
{
"ö", "ä", "ü", "Ö", "Ä", "Ü", "ß",
"?", "\", ",", ":", ";", "#", "+", "~", "!", "\"", "§", "$", "%",
"&", "(", ")", "=", "<", ">", "{", "[", "]", "}", "/", "â", "ê",
"î", "ô", "û", "Â", "Ê", "Î", "Ô", "Û", "á","ć", "é", "í", "ó", "ú",
"Á", "É", "Í", "Ó", "Ú", "à", "è", "ì", "ò", "ó", "ù", "Á", "É", "Í",
"Ó", "Ú", "°", "³", "²", "€", "|", "^", "`", "´", "'", " ", "@",
"~", "*"
};
public final static String charsHtml[] =
{
"ö", "ä", "ü", "Ö", "Ä", "Ü",
"ß", "?", "\", ",", ":", ";", "#", "+", "˜", "!", "\"",
"§", "$", "%", "&", "(", ")", "=", "<", ">", "{",
"[", "]", "}", "/", "â", "ê", "î", "ô",
"û", "Â", "Ê", "Î", "Ô", "Û",
"á", "é", "í", "ó", "ú",
"Á", "É", "Í", "Ó", "Ú",
"à", "è", "ì", "ò", "Ù",
"À", "È", "Ì", "Ò", "Ù",
"°", "³", "²", "€", "|", "ˆ", "`",
"´", "'", " ", "@", "~", "*"
};
public final static String entities[] = {
"F6", "E4", "FC", "D6", "C4",
"DC", "DF", "3F", "5C", "2C", "3A", "3B", "23", "2B", "7E", "21",
"22", "A7", "24", "25", "26", "28", "29", "3D", "3C", "3E", "7B",
"5B", "5D", "7D", "2F", "E2", "EA", "EE", "F4", "FB", "C2", "CA",
"CE", "D4", "DB", "E1", "E9", "ED", "F3", "FA", "C1", "C9", "CD",
"D3", "DA", "E0", "E8", "EC", "F2", "F9", "C1", "C9", "CD", "D3",
"DA", "B0", "B3", "B2", "80", "7C", "5E", "60", "B4", "27", "20",
"40", "98", "2A"
};
public static String inputToChar(String input) {
return (inputTo(input, chars));
}
public static String inputTo(String input, String[] tc) {
StringBuilder sb = new StringBuilder();
boolean entity = false;
input = input.replace ('+', ' ');
String tokens = tc == charsHtml ? "%<>" : "%";
for (StringTokenizer st = new StringTokenizer (input, tokens, true); st.hasMoreTokens(); ) {
String token = st.nextToken();
if (entity) {
boolean replaced = false;
for (int i = 0; i < entities.length; i++) {
if (token.startsWith (entities[i])) {
sb.append (tc[i]);
sb.append (token.substring (2));
replaced = true;
break;
}
}
if (!replaced) {
sb.append (token);
}
entity = false;
}
else if (token.equals ("%")) {
entity = true;
continue;
}
else if (token.equals ("<")) {
sb.append ("<");
}
else if (token.equals (">")) {
sb.append (">");
}
else {
sb.append (token);
}
}
return (sb.toString ());
}
public static void main(String [] args) {
String person1 = CharDecoder.inputToChar("Lukić");
System.out.println(person1);
}
}
为了让这个问题更直接ward,我删除了 JDBC 代码(一个简单的 JDBC 更新查询),只创建了一个 main() 方法。当我 运行 这个 main() 方法时,输出是:
Lukić
这很好,也是我想要的。但是,当我使用 Spring JDBC 更新它时,在 MySQL 数据库(table 的默认字符集是 UTF-8)中它变成:
Luki?
这肯定发生在数据库方面,我应该更改它吗(table 的默认字符集为 LATIN1)?
我是否必须将整个数据库的默认字符集更改为 LATIN1?我只是抛出一些想法...
有没有办法在不更改默认字符集的情况下解决这个问题(不想破坏任何现有数据)...
useUnicode=yes&characterEncoding=UTF-8
将此放入您的数据库url
如果你想拥有完整的 Unicode 支持,你不妨一路走下去:
character_set_server=utf8mb4
参见:
具有来自外部 REST / JSON 数据源的值作为特殊字符。我使用预先存在的实用程序 CharDecoder.java 对其进行转换,它保持不变,但在将其插入 MySQL 数据库(默认字符集为 UTF-8)后,它从 ć 变为 ?.
我的程序流程是这样的:
外部数据源发送 JSON --> CharDecoder(在 tomcat7 中的 war 文件中,处理特殊字符)然后填充一行 --> 在 MySQL 数据库中。
MySQL 数据库中的最终结果是无效字符。
开发环境信息:
我正在使用 Java 1.7.
Maven 3.3.3,在我的 pom.xml 的
<properties>
标签中:< project.build.sourceEncoding > UTF-8 < /project.build.sourceEncoding >
MacOS 上的 Eclipse Oxygen。
在 macOS 上 运行ning Eclipse Oxygen - 在项目的属性视图中(单击项目和 ⌘I 也称为 COMMAND+I),它指出文本文件编码为 UTF-8。
当我使用代码库中的实用程序 class 转换它时,它可以工作,但是当更新 MySQL 数据库中的行时(table 的默认字符集是UTF-8) 它变成了一个无效的字符。
所以,我将这个字符添加到我的字符数组中:“ć”(它位于以“î”开头的同一行)。
public class CharDecoder {
public final static String chars [] =
{
"ö", "ä", "ü", "Ö", "Ä", "Ü", "ß",
"?", "\", ",", ":", ";", "#", "+", "~", "!", "\"", "§", "$", "%",
"&", "(", ")", "=", "<", ">", "{", "[", "]", "}", "/", "â", "ê",
"î", "ô", "û", "Â", "Ê", "Î", "Ô", "Û", "á","ć", "é", "í", "ó", "ú",
"Á", "É", "Í", "Ó", "Ú", "à", "è", "ì", "ò", "ó", "ù", "Á", "É", "Í",
"Ó", "Ú", "°", "³", "²", "€", "|", "^", "`", "´", "'", " ", "@",
"~", "*"
};
public final static String charsHtml[] =
{
"ö", "ä", "ü", "Ö", "Ä", "Ü",
"ß", "?", "\", ",", ":", ";", "#", "+", "˜", "!", "\"",
"§", "$", "%", "&", "(", ")", "=", "<", ">", "{",
"[", "]", "}", "/", "â", "ê", "î", "ô",
"û", "Â", "Ê", "Î", "Ô", "Û",
"á", "é", "í", "ó", "ú",
"Á", "É", "Í", "Ó", "Ú",
"à", "è", "ì", "ò", "Ù",
"À", "È", "Ì", "Ò", "Ù",
"°", "³", "²", "€", "|", "ˆ", "`",
"´", "'", " ", "@", "~", "*"
};
public final static String entities[] = {
"F6", "E4", "FC", "D6", "C4",
"DC", "DF", "3F", "5C", "2C", "3A", "3B", "23", "2B", "7E", "21",
"22", "A7", "24", "25", "26", "28", "29", "3D", "3C", "3E", "7B",
"5B", "5D", "7D", "2F", "E2", "EA", "EE", "F4", "FB", "C2", "CA",
"CE", "D4", "DB", "E1", "E9", "ED", "F3", "FA", "C1", "C9", "CD",
"D3", "DA", "E0", "E8", "EC", "F2", "F9", "C1", "C9", "CD", "D3",
"DA", "B0", "B3", "B2", "80", "7C", "5E", "60", "B4", "27", "20",
"40", "98", "2A"
};
public static String inputToChar(String input) {
return (inputTo(input, chars));
}
public static String inputTo(String input, String[] tc) {
StringBuilder sb = new StringBuilder();
boolean entity = false;
input = input.replace ('+', ' ');
String tokens = tc == charsHtml ? "%<>" : "%";
for (StringTokenizer st = new StringTokenizer (input, tokens, true); st.hasMoreTokens(); ) {
String token = st.nextToken();
if (entity) {
boolean replaced = false;
for (int i = 0; i < entities.length; i++) {
if (token.startsWith (entities[i])) {
sb.append (tc[i]);
sb.append (token.substring (2));
replaced = true;
break;
}
}
if (!replaced) {
sb.append (token);
}
entity = false;
}
else if (token.equals ("%")) {
entity = true;
continue;
}
else if (token.equals ("<")) {
sb.append ("<");
}
else if (token.equals (">")) {
sb.append (">");
}
else {
sb.append (token);
}
}
return (sb.toString ());
}
public static void main(String [] args) {
String person1 = CharDecoder.inputToChar("Lukić");
System.out.println(person1);
}
}
为了让这个问题更直接ward,我删除了 JDBC 代码(一个简单的 JDBC 更新查询),只创建了一个 main() 方法。当我 运行 这个 main() 方法时,输出是:
Lukić
这很好,也是我想要的。但是,当我使用 Spring JDBC 更新它时,在 MySQL 数据库(table 的默认字符集是 UTF-8)中它变成:
Luki?
这肯定发生在数据库方面,我应该更改它吗(table 的默认字符集为 LATIN1)?
我是否必须将整个数据库的默认字符集更改为 LATIN1?我只是抛出一些想法...
有没有办法在不更改默认字符集的情况下解决这个问题(不想破坏任何现有数据)...
useUnicode=yes&characterEncoding=UTF-8
将此放入您的数据库url
如果你想拥有完整的 Unicode 支持,你不妨一路走下去:
character_set_server=utf8mb4
参见: