Обратитесь к этому tweet и следующему потоку, мы пытаемся Храните подобный твит в базу данных. Я не могу сохранить этот твит в MySQL, я хотел бы знать, как идентифицировать, если строка содержит символ, который не может быть обработан набором символов utf8-mb4, поэтому я могу избежать его сохранения.
Как определить, содержит ли строка специальный символ, который не может быть сохранен с использованием набора символов utf8-mb4
Ответ 1
Символ, который создает для вас проблему, - это U+1F603 SMILING FACE WITH OPEN MOUTH
, у которого значение не представлено в 16 бит. При преобразовании в UTF-8 значения байта f0 9f 98 83
, которые должны соответствовать без проблем в столбце MySQL набора символов utf8mb4
, поэтому я согласен с другими комментаторами в том, что он не выглядит проблемой MySQL. Если вы попытаетесь повторно вставить этот твит, запишите все операторы SQL, полученные MySQL, чтобы определить, повреждены ли символы до или после отправки их в MySQL.
Ответ 2
Вместо того, чтобы найти специальный символ строки, вы можете сделать одну вещь вы можете преобразовать строку в шестнадцатеричный формат, а затем назад вы можете преобразовать ее в предыдущую строку
public static synchronized String toHex(byte [] buf){
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10){
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
Используя приведенную ниже функцию, вы можете преобразовать обратно в исходную строку
public synchronized static byte[] hexToBytes(String hexString) {
HexBinaryAdapter adapter = new HexBinaryAdapter();
byte[] bytes = adapter.unmarshal(hexString);
return bytes;
}
Ответ 3
Если вы хотите избежать хранения неприятных символов (редких причудливых символов вне базового многоязычного плана, которые дают вам проблемы), вы можете анализировать символы String
и отбрасывать String
, если он содержит кодовые страницы, для которых Character.charCount
возвращает 2
, или для которого Character.isSupplementaryCodePoint
возвращает true
.
Таким образом, как вы просили, вы можете избежать сохранения тех строк, которые (по какой-то причине) имеют проблемы с вашей СУБД.
Источники: см. javadoc для
-
Character.charCount
-
Character.isSupplementaryCodePoint
и, пока вы на нем
-
String.codePointAt
-
String.codePointCount