Не удается вставить нелатинские символы в MySQL - PullRequest
4 голосов
/ 04 мая 2010

Я пишу веб-приложение, используя MySQL версии 5.1.45, Tomcat 5.5.28 и Hibernate 3

При попытке сохранить строку, содержащую нелатинские символы (например, Упячка), возникает ошибка:

1589 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1366, SQLState: HY000
1589 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Incorrect string value: '\xD0\xA3\xD0\xBF\xD1\x8F...' for column 'name' at row 1

Настройки соединения Hibernate

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/E2012?characterEncoding=UTF8&amp;useUnicode=true</property>
<property name="connection.username">***</property>
<property name="connection.password">***</property>
<property name="hibernate.connection.charSet">UTF8</property>

MySQL config My.cnf

[client]
 default-character-set=utf8

[mysqld]
 default-character-set=utf8

Даже имя набора запросов utf-8 не решает проблему

Спасибо за помощь!

Ответы [ 2 ]

7 голосов
/ 04 мая 2010

В UTF-8 Упячка фактически должно быть представлено как \x423\x43F\x44F\x447\x43A\x430. \xD0\xA3\xD0\xBF\xD1\x8F... означает, что они были неправильно закодированы с использованием ISO-8859-1.

Вот тестовый фрагмент, который доказывает это:

String s = new String("Упячка".getBytes("UTF-8"), "ISO-8859-1"); // First decode with UTF-8, then (incorrectly) encode with ISO-8859-1.
for (char c : s.toCharArray()) {
    System.out.printf("\\x%X", (int) c);
}

Какие отпечатки

\xD0\xA3\xD0\xBF\xD1\x8F\xD1\x87\xD0\xBA\xD0\xB0

Так что ваша проблема должна быть решена на шаг раньше. Поскольку вы говорите о веб-приложении Java, и эта строка, вероятно, является результатом пользовательского ввода, вы уверены, что позаботились о кодировках HTTP-запросов и ответов? Во-первых, в JSP необходимо добавить следующее в начало JSP:

<%@ page pageEncoding="UTF-8" %>

Это не только отображает страницу в UTF-8, но также неявно устанавливает заголовок ответа HTTP Content-Type, указывающий клиенту, что страница отображается с использованием UTF-8, чтобы клиент знал что он должен отображать любой контент и обрабатывать любые формы, используя ту же кодировку.

Теперь, часть HTTP-запроса, для GET-запросов вам нужно настроить рассматриваемый контейнер сервлетов. Например, в Tomcat это вопрос установки атрибута URIEncoding HTTP-соединителя в /conf/server.xml соответственно. Для запросов POST это должно быть уже сделано клиентом (веб-браузером) достаточно умным, чтобы использовать кодировку ответа, как указано в JSP. Если этого не произойдет, вам нужно будет ввести Filter, который проверяет и устанавливает кодировку запроса.

Для получения дополнительной справочной информации вы можете найти эту статью полезной.


Помимо всего этого, в MySQL есть еще одна проблема с символами Unicode. Он поддерживает только символы UTF-8 до 3 байтов , но не 4 байта. Другими словами, поддерживается только диапазон BMP из 65535 символов, за исключением того, что нет. PostgreSQL, например, полностью поддерживает это. Это может не повредить вашему веб-приложению, но об этом, безусловно, следует помнить.

1 голос
/ 04 мая 2010

Попробуйте использовать UTF-8 для параметра characterEncoding в вашем URL JDBC, а не UTF8 (обратите внимание на тире).

Это случилось со мной раньше.

...