Java emoji持久化mysql過程詳解
前言
好久沒有更新博客了,今天和大家分享一個(gè)關(guān)于emoji表情持久化問題,相信做web開發(fā)的都遇到過這樣的問題,因?yàn)槲覀冎續(xù)ysql的utf-8字符集保存不了保存不了表情字符,這是為什么呢?因?yàn)槠胀ǖ淖址蛘弑砬槎际钦嘉?個(gè)字節(jié),所以utf8足夠用了,但是移動(dòng)端的表情符號占位是4個(gè)字節(jié),普通的utf8就不夠用了,為了應(yīng)對無線互聯(lián)網(wǎng)的機(jī)遇和挑戰(zhàn)、避免 emoji 表情符號帶來的問題、涉及無線相關(guān)的 MySQL 數(shù)據(jù)庫建議都提前采用 utf8mb4 字符集,這必須要作為移動(dòng)互聯(lián)網(wǎng)行業(yè)的一個(gè)技術(shù)選型的要點(diǎn)。
好了看到上面的結(jié)果你是不是已經(jīng)去修改數(shù)據(jù)庫字符集了,如果你是個(gè)人項(xiàng)目或小項(xiàng)目上面的方法倒是一個(gè)解決方法,但是對于一個(gè)目前正在服務(wù)5000W用戶的系統(tǒng),上面的方式就有點(diǎn)不合適了,針對這種情況我這邊總結(jié)了三種處理方式,下面分享給大家:
1、既然是由于移動(dòng)端的表情符號占位是4個(gè)字節(jié),那我們直接把數(shù)據(jù)轉(zhuǎn)換后保存。
1.URLEncoder.encode(String s, String enc)
使用指定的編碼機(jī)制將字符串轉(zhuǎn)換為 application/x-www-form-urlencoded 格式
URLDecoder.decode(String s, String enc)
使用指定的編碼機(jī)制對 application/x-www-form-urlencoded 字符串解碼。
2、方法一的處理太粗躁,有沒有更好的解決辦法呢?使用輕量級工具emoji-java處理emoji表情字符
github地址:https://github.com/vdurmont/emoji-java
具體使用方式,大家可以進(jìn)入git中自行查看。
3、有了上面兩種方式,你是不是已經(jīng)滿足了,最為自己最推崇的emoji處理方式,下面才是重點(diǎn),首先說一下上面兩種方式存在的問題:第一種方式,數(shù)據(jù)經(jīng)過轉(zhuǎn)換,相當(dāng)于加密,我們將無法直接查看到數(shù)據(jù)的原始內(nèi)容,由其對于需要進(jìn)行搜索的業(yè)務(wù)場景,將是一件很困難的事情;第二種方式,雖然避免了第一種方式存在的問題,但是它基于表情的對照表進(jìn)行匹配轉(zhuǎn)換的,也就意味著對于一些新表情,無法做到轉(zhuǎn)換,這就會(huì)導(dǎo)致我們數(shù)據(jù)插入繼續(xù)出現(xiàn)問題,這是它第一個(gè)問題,第二點(diǎn)在于它將表情轉(zhuǎn)化為對應(yīng)的匹配規(guī)則,說白一點(diǎn)就是轉(zhuǎn)化為英文描述,就是這個(gè)轉(zhuǎn)化,原本4個(gè)字節(jié)的表情,它可能給你轉(zhuǎn)成了10個(gè)字節(jié)甚至更多。好了說了這么多下面我們看一下我最后的終極解決方法:
/** * @Author: gaoshang * @Description: * @Date: 2019/7/19 */ public class EmojiUtil { /** * 將文本中的表情轉(zhuǎn)為十六進(jìn)制 * <p> * * @param input * @return */ public static String parseFromAliases(String input) { if (input == null) { return input; } return stringToUnicode(input); } /** * 將文本中的十六進(jìn)制轉(zhuǎn)為表情 * <p> * * @param input * @return */ public static String parseToAliases(String input) { if (input == null) { return input; } return unicodeToString(input); } /** * 字符串轉(zhuǎn)unicode * * @param str * @return */ public static String stringToUnicode(String str) { StringBuilder sb = new StringBuilder(); StringBuilder cacheSB = new StringBuilder(); char[] c = str.toCharArray(); for (int i = 0; i < c.length; i++) { if (!isEmojiCharacter(c[i])) { if (cacheSB.length() > 0) { sb.append("\\u").append(cacheSB); cacheSB.delete(0, cacheSB.length()); } sb.append("\\u").append("[").append(Integer.toHexString(c[i])).append("]"); } else { if (c[i] == '[' || c[i] == '\\' || c[i] == ']') { if (cacheSB.length() > 0) { sb.append("\\u").append(cacheSB); cacheSB.delete(0, cacheSB.length()); } sb.append("\\u").append(c[i]); } else { cacheSB.append(c[i]); } } } if (cacheSB.length() > 0) { if (sb.length() > 0) { sb.append("\\u"); } sb.append(cacheSB); } return sb.toString(); } /** * unicode轉(zhuǎn)字符串 * * @param unicode * @return */ public static String unicodeToString(String unicode) { StringBuilder sb = new StringBuilder(); String[] hex = unicode.split("\\\\u"); for (int i = 0; i < hex.length; i++) { if (hex[i].indexOf("[") == 0 && hex[i].indexOf("]") == hex[i].length() - 1) { try { int index = Integer.parseInt(hex[i].substring(1, hex[i].length() - 1), 16); sb.append((char) index); } catch (NumberFormatException e) { sb.append(hex[i]); } } else { sb.append(hex[i]); } } return sb.toString(); } private static boolean isEmojiCharacter(char codePoint) { return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)); } }
好了就先這樣,歡迎大家提出不同的看法,已經(jīng)好的解決方案。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JSON數(shù)據(jù)轉(zhuǎn)換成Java對象的方法
就目前來講,將Java對象轉(zhuǎn)換成JSON對象還是相當(dāng)簡單的,但是 將JSON對象轉(zhuǎn)換成Java對象,就相對比較復(fù)雜了些2014-03-03Java中使用Preconditions來檢查傳入?yún)?shù)介紹
這篇文章主要介紹了Java中使用Preconditions來檢查傳入?yún)?shù)介紹,本文只是作為一個(gè)簡單的用法介紹,需要的朋友可以參考下2015-06-06Nacos+Spring Cloud Gateway動(dòng)態(tài)路由配置實(shí)現(xiàn)步驟
Nacos最近項(xiàng)目一直在使用,本文通過gateway、nacos-consumer、nacos-provider三個(gè)簡單模塊來展示:Nacos下動(dòng)態(tài)路由配置,,感興趣的小伙伴們可以參考一下2021-08-08java使用Rxtx實(shí)現(xiàn)串口通信調(diào)試工具
這篇文章主要為大家詳細(xì)介紹了java使用Rxtx實(shí)現(xiàn)簡單串口通信調(diào)試工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12