项目场景:
使用微信账号进行账号的注册
问题描述:
注册接口报错,我看了错误信息如下所示:
Incorrect string value: '\xF0\x9F\xA4\x97 3...' for column 'nick_name' at row 1
原因分析:
这应该说的是微信传过来的nickName字段名了,既然这个报错我就要看下用户他的昵称是什么,居然发现昵称是一个表情符号。
查询后发现emoji表情符采用Unicode 6标准,采用4个byte字节存储一个emoji表情符,而我们的mysql数据库采用UTF-8编码格式时,采用3个byte字节存储一个字符,这样插入数据库就会报错。好在mysql5.5.3之后新增了一个utf8mb4字符集,专门用来兼容4字节的Unicode字符。
解决方案:
第一种
把数据库和表的编码都改成utf8mb4,这个编码可以适配所有的符号
第二种
在存储昵称前,对昵称进行加密, 在获取昵称前,对加密的昵称进行解密
第三种
在保存昵称的地方,直接对昵称的特殊图片符号进行过滤,如下:
EmojiStringUtils.replaceEmoji(nickName);
public class EmojiStringUtils {/*** @Title:判断是否存在特殊字符串* @param* @author:yanbing* @date:-12-05 10:14*/public static boolean hasEmoji(String content){Pattern pattern = pile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]");Matcher matcher = pattern.matcher(content);if(matcher .find()){return true; }return false;}/*** @Title:替换字符串中的emoji字符* @param* @author:yanbing* @date:-12-05 10:17*/public static String replaceEmoji(String str){if(!hasEmoji(str)){return str;}else{str=str.replaceAll("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]", " ");return str;}}}