JAVA解決Emoji表情存儲至Mysql報錯問題


保存微信昵稱時,Mysql報錯。

Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98...' for column 'nick_name' at row 1
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)

報錯原因:

UTF-8編碼有可能是兩個、三個、四個字節。Emoji表情是4個字節,而Mysql的utf8編碼最多3個字節,所以數據插不進去。

 

網上解決辦法:

1、修改my.ini [mysqld] character-set-server=utf8mb4在后台配置mysql連接參數中,不要加characterEncoding參數。 不加這個參數時,默認值就時autodetect。將已經建好的表也轉換成utf8mb4。命令:(將TABLE_NAME替換成你的表名)

ALTER TABLE `TABLE_NAME` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 
將需要使用emoji的字段設置類型為utf8mb4_general_ci: 
ALTER TABLE `TABLE_NAME`MODIFY COLUMN `COLUMN_NAME`  text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

 

照做之后,發現並沒有解決問題。找不到原因。等以后空閑時間慢慢調錯。先將這次BUG修復。選用另一種方法。

1、存儲nickname的時候,先將nickname用base64編碼。我照做以后,發現還是有問題。最后,使用了一種稍麻煩的辦法。

String encodeNickname = new String(Base64.getEncoder().encode("Nickname".getBytes()));

2、取出的時候,先將nickname用base64解碼。

String decodeNickname = new String(Base64.getDecoder().decode(encodeNickname.getBytes()));

3、數據庫中的nickname手動用base64編碼更新。

 

結束上述步驟后,查看后台發現傻了眼。新增的用戶nickname可以正常顯示emoji表情了。但是之前手動編碼的nickname全部亂碼了。

沒有找到原因。以為是沒有加上編碼格式的原因。更改代碼:

String encodeNickname = new String (Base64.getEncoder().encode("Nickname".getBytes()),"utf-8");
System.out.println("編碼后:"+encodeNickname);
String decodeNickname = new String (Base64.getDecoder().decode(encodeNickname.getBytes()),"utf-8");
System.out.println("解碼后:"+decodeNickname);

還是亂碼!百思不得其解。福至心靈,拿gbk將之前編碼的數據解碼試了下。發現顯示正常了。

new String (Base64.getDecoder().decode(encodeNickname.getBytes()),"gbk");

重新把之前nickname用gbk解碼獲取用戶昵稱,然后用utf-8編碼存儲,utf-8解碼。一切正常了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM