Emoji表情字符如今在APP已經普遍支持了。可是MySQL的UTF8編碼對Emoji字符的支持卻不是那麼好。因此咱們常常會遇到這樣的異常:
Java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8E' for column 'nick' at row 1
1
緣由是Mysql裏UTF8編碼最多隻能支持3個字節,而Emoji表情字符使用的UTF8編碼,不少都是4個字節,有些甚至是6個字節。
解決的方案有兩種:
使用utf8mb4的mysql編碼來容納這些字符。
過濾掉這些特殊的表情字符。
方法1:使用utf8mb4的mysql編碼來容納這些字符
注意:要使用utf8mb4類型,首先要保證Mysql版本要不低於 MySQL 5.5.3。
第一步:在mysql的安裝目錄下找到my.ini,做以下修改
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
修改後重啓Mysql
第二步:將已經建好的表也轉換成utf8mb4
alter table TABLE_NAME convert to character set utf8mb4 collate utf8mb4_bin;
1
將TABLE_NAME替換成你的表名。而後就OK了。
網上流傳的一個版本增長了一個步驟,就是以root身份登陸Mysql,修改環境變量,將
character_set_client,character_set_connection,character_set_database,character_set_results,character_set_server
1
都修改爲utf8mb4。不過我沒有作這一步,也正常,因此多是這一步是多餘的。
方法2:過濾掉這些特殊的字符
public class charUtil {
/**
* 替換四個字節的字符 '\xF0\x9F\x98\x84\xF0\x9F)的解決方案 ��
*/
public static String removeFourChar(String content) {
byte[] conbyte = content.getBytes();
for (int i = 0; i < conbyte.length; i++) {
if ((conbyte[i] & 0xF8) == 0xF0) {
for (int j = 0; j < 4; j++) {
conbyte[i + j] = 0x30;// 0x30 int=48 字符=0
}
i += 3;
}
}
content = new String(conbyte);
return content.replaceAll("0000", "");
}
/**
* 將emoji表情替換成*
* @return 過濾後的字符串
* 過濾的方式很簡單,直接使用正則表達式匹配編碼範圍,而後替換就好了。
*/
public static String filterEmoji(String source) {
if (StringUtils.isNotBlank(source)) {
return source.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "*");
} else {
return source;
}
}
public static void main(String[] arg) {
try {
System.err.println("測試->將emoji表情替換成*");
String text = "This is a smiley \uD83C\uDFA6 face\uD860\uDD5D \uD860\uDE07 \uD860\uDEE2 \uD863\uDCCA \uD863\uDCCD \uD863\uDCD2 \uD867\uDD98 ";
System.out.println(text);
System.out.println(text.length());
System.out.println(text.replaceAll("[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]", "*"));
System.out.println(filterEmoji(text));
//輸出結果
//This is a smiley �� face�� �� �� �� �� �� ��
//45
//This is a smiley * face�� �� �� �� �� �� ��
//This is a smiley * face* * * * * * *
System.err.println("測試->替換四個字節的字符 '\\xF0\\x9F\\x98\\x84\\xF0\\x9F)的解決方案 ��");
String title = "ff的范德薩分��������Llfldakf;dsk。f������������daslfjdsa;lfkjdsd'j'l'f'k'd'j'sa'l'k";
System.out.println(removeFourChar(title));
//輸出結果:ff的范德薩分Llfldakf;dsk。fdaslfjdsa;lfkjdsd'j'l'f'k'd'j'sa'l'k
} catch (Exception ex) {
ex.printStackTrace();
}
}
}