保存微信昵稱時,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解碼。一切正常了。
