Cause: java.sql.SQLException: Incorrect string value: ‘\\xF0\\x9F\\x9F\\xA6\\xE6\\x98...‘

Cause: java.sql.SQLException: Incorrect string value: '\\xF0\\x9F\\x9F\\xA6\\xE6\\x98...'

咋一眼看到这个错,反应过来是入库的内容包含了emoji表情, 或者特殊符号。

因为数据库中的字符集设置的未utf8,而mysql中的utf8是有缺陷的,那就是编码最大是3个字节,而我们在开发中的UTF-8编码最大是四个字节,像emoji表情就是4个字节,这里可以验证这个猜想。

取前四个字节找个在线转换网站便可,转换如下:
Cause: java.sql.SQLException: Incorrect string value: ‘\\xF0\\x9F\\x9F\\xA6\\xE6\\x98...‘_第1张图片

这明显是个特殊符号,所以导致入库失败。

解决办法:

1. mysql有对这个缺陷修复,即utf8mb4,这是utf8超集,兼容utf8,并且编码最大字节是4个字节,特殊字符和emoji表情存入,毫无问题(这也是最好的办法,只是对mysql版本有要求, 一般5.6+)

2. 如果功能已经上线,有大量线上数据,以及mysql版本不支持,不能轻易去修改字符集,那也可以通过encode编码入库,出库时在用decode解码,但是这种方式也很麻烦,因为如果涉及改造地方太多,那将花费大量时间

3. 过滤emoji表情,使用工具EmojiParser,示例如下:

if (!name.equals(EmojiParser.parseToAliases(name))) {
                try {
                    String encode = URLEncoder.encode(name, "UTF-8");
                    String decode = URLDecoder.decode(encode, "UTF-8");
                    log.info("部门名称包含emoji表情: {}, encode编码后: {}, decode解码后: {}", name, encode, decode);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }

这种方式对用户不是很友好,并且像上面那个字符还不属于emoji表情,是无法用这个过滤的。

总结:如果是在功能开发前,想到这个问题,避免出现这种问题是最好的,出于业务考虑,一般和微信等有关联的情况下,条件反射想到这个问题,当然这都是后话,只能做到以后避免。

你可能感兴趣的:(java,mysql,mysql,emoji表情,utf8mb4)