的字符集,这个字符集能够支持 4 字节的 UTF8 编码的字符。 utf8mb4 字符集能够完美地向下兼容 utf8
字符串。在数据存储方面,当一个普通中文字符存入数据库时仍然占用 3 个字节,在存入一个 Unified Emoji 表情的时候,它会自动占用 4
个字节。所以在输入输出时都不会存在乱码的问题了。由于 utf8mb4 是 utf8 的超集,从 utf8 升级到 utf8mb4
不会有任何问题,直接升级即可;如果从别的字符集如 gb2312 或者 gbk 转化而来,一定要先备份数据库。然后,修改 MySQL 的配置文件
/etc/my.cnf,修改连接默认字符集为 utf8mb4 ,然后在连接数据库以后首先执行一句 SQL: SET NAMES
utf8mb4。
1. 修改my.cnf 或 my.ini
[mysqld]
character-set-server=utf8mb4
[mysql]
default-character-set=utf8mb4
修改后重启Mysql
登陆MYSQL, show variables like 'character%'可以查看编码是否已经修改成功。
2、修改数据库和数据表为相应的 utf8mb4 格式。
alter table TABLE_NAME convert to character set utf8mb4 collate utf8mb4_bin
3、在代码中,连接数据库成功后,执行 "set names utf8mb4"
网上已经有开源的了!http://code.iamcal.com/php/emoji/ 你参考下iOS 5.0之前,苹果都是采用3个字节来承接 emoji 表情,Java 的普通 char 可以支持显示。但 iOS 5.0 之后, 苹果升级了系统自带的 emoji 表情输入法,用的 Unicode 6 标准来统一,是采用4个 bytes 来承接一个 emoji 表情。如果不做处理的话,这种表情直接存储到 mysql5.5 以下的数据库是会报错的。就像这两个表情一样:口口, 在 Windows 8 以下估计都不支持显示,可能会显示成框框,可能压根就是空白, 你可以在 Mac 中使用Safari 浏览器中,就可以看到。经过测试,在 Mac 就算用 Chrome 浏览器(Version 25.0.1364.172)也是不行的。
这种数据在 Mysql 5.5 之前,UTF-8 支持1-3个字节的编码,从 Mysql5.5 开始后,可以支持4个字节的 UTF 编码,但要特殊标记。修改 Mysql 相应存储字段为 utf8mb4 。修改语句如下:
1ALTER TABLE table_name
2 MODIFY COLUMN content varchar(500) CHARACTER
3 SET utf8mb4 COLLATE utf8mb4_unicode_ci
4 DEFAULT NULL COMMENT 'content of message'
在某种业务情景下,我们可以选择过滤掉这种“非法”的字符。我采用的方式是,在字符上面做 *** 作,下面是Java示例代码,核心的代码附上,应该是 无法直接下载就能够编译,你得小小的做一些微调,没有额外的依赖:
01public class EmojiFilter {
02
03/**
04 * 检测是否有emoji字符
05 * @param source
06 * @return 一旦含有就抛出
07 */
08public static boolean containsEmoji(String source) {
09if (StringUtils.isBlank(source)) {
10return false
11}
12
13int len = source.length()
14
15for (int i = 0i <leni++) {
16char codePoint = source.charAt(i)
17
18if (isEmojiCharacter(codePoint)) {
19//do nothing,判断到了这里表明,确认有表情字符
20return true
21}
22}
23
24return false
25}
26
27private static boolean isEmojiCharacter(char codePoint) {
28return (codePoint == 0x0) ||
29(codePoint == 0x9) ||
30(codePoint == 0xA) ||
31(codePoint == 0xD) ||
32((codePoint >= 0x20) &&(codePoint <= 0xD7FF)) ||
33((codePoint >= 0xE000) &&(codePoint <= 0xFFFD)) ||
34((codePoint >= 0x10000) &&(codePoint <= 0x10FFFF))
35}
36
37/**
38 * 过滤emoji 或者 其他非文字类型的字符
39 * @param source
40 * @return
41 */
42public static String filterEmoji(String source) {
43
44if (!containsEmoji(source)) {
45return source//如果不包含,直接返回
46}
47//到这里铁定包含
48StringBuilder buf = null
49
50int len = source.length()
51
52for (int i = 0i <leni++) {
53char codePoint = source.charAt(i)
54
55if (isEmojiCharacter(codePoint)) {
56if (buf == null) {
57buf = new StringBuilder(source.length())
58}
59
60buf.append(codePoint)
61} else {
62}
63}
64
65if (buf == null) {
66return source//如果没有找到 emoji表情,则返回源字符串
67} else {
68if (buf.length() == len) {//这里的意义在于尽可能少的toString,因为会重新生成字符串
69buf = null
70return source
71} else {
72return buf.toString()
73}
74}
75
76}
77}
还有优化的空间,但是已经能够满足大多数情况的需求,附上单元测试(JUnit4):
01public class EmojiFilterTest {
02
03
04 /**
05 * 测试emoji表情
06 */
07@Test
08public void fileterEmoji() {
09String s = "<body>口口213这是一个有各种内容的消息, Hia Hia Hia !!!! xxxx@@@...*)!" +
10"(@*$&@(!)@*)!&$!)@^%@(!. 口口口], "
11String c = Utils.filterEmoji(s)
12assertFalse(s.equals(c))
13String expected = "<body>213这是一个有各种内容的消息, Hia Hia Hia !!!! xxxx@@@...*)" +
14"!(@*$&@(!)@*)!&$!)@^%@(!. ], "
15assertEquals(expected, c)
16//assertSame(c, expected)
17assertSame(expected, "<body>213这是一个有各种内容的消息, Hia Hia Hia !!!! xxxx@@@...*)" +
18"!(@*$&@(!)@*)!&$!)@^%@(!. ], ")
19assertSame(c, Utils.filterEmoji(c))
20}
21
22}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)