1、在做微信小程序的时候遇到了用户昵称中含有emoj表情无法入库的情况。
### Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x80' for column 'nick' at row 1
; uncategorized SQLException for SQL []; SQL state [HY000]; error code [1366]; Incorrect string value: '\xF0\x9F\x98\x80' for column 'nick' at row 1; nested exception is java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x80' for column 'nick' at row 1
2、错误很明显,用户昵称入库失败,马上想到可能是特殊字符或者表情,首先解决报错,保证流程正常,就是需要把用户昵称中的emoj表情替换掉。
//替换emoj
"??1".replaceAll("[^\\u0000-\\uFFFF]", "?");
3、进一步解决问题,对用户昵称进行编码存库,然后前端获取昵称的时候进行解码,这样小程序可以完整的显示用户昵称。
try {
System.out.println(Base64.encodeBase64String("?".getBytes("utf-8")));
} catch (UnsupportedEncodingException e1) {
}
String nickname = "8J+NiQ==";
try {
nickname = new String(Base64.decodeBase64(nickname.getBytes()), "utf-8");
System.out.println(nickname);
} catch (UnsupportedEncodingException e) {
}
4、这样存在一个问题,就是对所有昵称进行编码之后,后台数据库存储的用户昵称都是编码后的字符,看起很怪。
5、可以通过设置涉及字段的字符编码,保证这个字段可以存储emoj表情。
MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。
将nick字段编码字符集 设置为utf8mb4,排序规则utf8mb4_general_ci,这样就可以插入emoj表情,有说法需要重启,我测试的时候不需要重启,设置之后可能还会出现插入错误,需要在配置文件中配置如下的东西。
druid连接池配置如下
<property name="connectionInitSqls" value="set names utf8mb4;"/>
BoneCP连接池配置如下
<property name="initSQL" value="set names utf8mb4;"/>