最近上线了新功能,昨晚一位同事告诉我,后台有报错,返回前端的信息是:
java.sql.SQLException:Incorrect String value:'\xF0\x9F\x98\x83' for column 'name' at row1
当时服务器是UTF-8编码,项目也是UTF-8编码,那么这个问题是如何产生的呢?
我想起info发布一边文章《记住,永远不要在MySQL中使用“utf8”》,里面提交到,MySQL的“utf8”实际上不是真正意义上的UTF-8。
MySQL的“utf8”只支持每个字符最多三个字节,而真正的 UTF-8 是每个字符最多四个字节。
MySQL 一直没有修复这个 bug,他们在 2010 年发布了一个叫作“utf8mb4”的字符集,绕过了这个问题。
现在网络仍然有大部分人在不同的关于技术的问答或者博客中建议开发者使用“utf8”,这些建议都是错误的。实际上,应该采用“utf8mb4”编码。
那文章总结了两点:
- MySQL 的“utf8mb4”是真正的“UTF-8”。
- MySQL 的“utf8”是一种“专属的编码”,它能够编码的 Unicode 字符并不多。
那么我们可以采用哪种方法解决文章开头碰到的问题?
- 修改数据库字符集。从MySQL 5.5.3版本开始,数据库可支持4个字节的utf8mb4 字符集,一个字符最多可以有4个字节,所以能支持更多的字符集,故能存储Emoji表情符号。从 mysql 5.5.3 之后版本基本可以无缝升级到 utf8mb4 字符集。同时,utf8mb4兼容utf8字符集,utf8 字符的编码、位置、存储在utf8mb4与utf8字符集里一样的,不会对有现有数据带来损坏。
- 后端增加校验代码,防止用户提交带有表情符号的文本信息。