Java與Mysql開發中的特殊字元(包括Emoji)
阿新 • • 發佈:2019-02-04
背景知識
- emoji表情符號,是20世紀90年代由NTT Docomo慄田穣崇(Shigetaka Kurit)建立的,詞義來自日語(えもじ,e-moji,moji在日語中的含義是字元)。emoji可以使數字通訊做到讓人如同面對面交流,避免錯誤傳達資訊。
- 自蘋果公司釋出的iOS 5輸入法中加入了emoji後,這種表情符號開始席捲全球,目前emoji已被大多數現代計算機系統所相容的Unicode編碼採納,普遍應用於各種手機簡訊和社交網路中。
- 所謂Emoji就是一種在Unicode位於
\u1F601
-\u1F64F
區段的字元。這個顯然超過了目前常用的UTF-8字符集的編碼範圍\u0000
-\uFFFF
。
知識點
- 在Java裡UTF-8,只支援雙位元組即\u0000-\uFFFF,emoji(馬頭) => "\uD83D\uDC34"
- 查Symbola表,我們的目標物件大致是從
- 1F300-1F3FF => "\uD83C\uDF00" - "\uD83C\uDFFF"
- 1F400-1F4FF => "\uD83D\uDC00" - "\uD83D\uDCFF"
- 1F500-1F5FF => "\uD83D\uDD00" - "\uD83D\uDDFF"
- 1F600-1F6FF => "\uD83D\uDE00" - "\uD83D\uDEFF"
- 1F700-1F7FF => "\uD83D\uDF00" - "\uD83D\uDFFF
編碼知識
Code | UTF-8 | UTF-16 LE | Surrogates |
---|---|---|---|
1F7FF | F0 9F 9F BF | 3D D8 FF DF | D83D DFFF |
UTF-16描述
Unicode的編碼空間從U+0000到U+10FFFF,共有1,112,064個碼位(code point)可用來對映字元. Unicode的編碼空間可以劃分為17個平面(plane),每個平面包含216(65,536)個碼位。17個平面的碼位可表示為從U+xx0000到U+xxFFFF,其中xx表示十六進位制值從0016到1016,共計17個平面。第一個平面稱為基本多語言平面(Basic Multilingual Plane,
UTF-16解碼
lead \ trail | DC00 | DC01 | … | DFFF |
---|---|---|---|---|
D800 | 10000 | 10001 | … | 103FF |
D801 | 10400 | 10401 | … | 107FF |
⋮ | ⋮ | ⋮ | ⋱ | ⋮ |
DBFF | 10FC00 | 10FC01 | … | 10FFFF |
示例:
例如U+10437編碼:
- 0x10437減去0x10000,結果為0x00437,二進位制為0000 0000 0100 0011 0111。
- 分割槽它的上10位值和下10位值(使用二進位制):0000000001 and 0000110111。
- 新增0xD800到上值,以形成高位:0xD800 + 0x0001 = 0xD801。
- 新增0xDC00到下值,以形成低位:0xDC00 + 0x0037 = 0xDC37。
- 下表總結了該轉換,以及其它。顏色指示如何從碼點位被分佈在所述的UTF-16位元組。由UTF-16編碼過程中加入附加位以黑色顯示。
字元 | 普通二進位制 | UTF-16二進位制 |
UTF-16 十六進位制 字元程式碼 |
UTF-16BE 十六進位制位元組 |
UTF-16LE 十六進位制位元組 |
|
---|---|---|---|---|---|---|
$ |
U+0024 |
0000 0000 0010 0100 |
0000 0000 0010 0100 |
0024 |
00 24 |
24 00 |
€ |
U+20AC |
0010 0000 1010 1100 |
0010 0000 1010 1100 |
20AC |
20 AC |
AC 20 |
U+10437 |
0001 0000 0100 0011 0111 |
1101 1000 0000 0001 1101 1100 0011 0111 |
D801 DC37 |
D8 01 DC 37 |
01 D8 37 DC |
|
U+24B62 |
0010 0100 1011 0110 0010 |
1101 1000 0101 0010 1101 1111 0110 0010 |
D852 DF62 |
D8 52 DF 62 |
52 D8 62 DF |
解決方案
一 資料庫
- jar包:mysql connector版本高於5.1.13
- mysql:utf8mb4的最低mysql版本支援版本為5.5.3+
- 從utf8改至utf8mb4,需要重啟mysql
- 由於RD不應更改mysql配置,所以需要在業務應用處,呼叫set names utf8mb4,以使資料以utf8mb4編碼儲存到資料庫
二 過濾
由於資料庫的治本方法建立在有資料儲存的所有涉獵系統都得滿足上述條件,所以並不是常常滿足。由此還需要一個治標的方法。
public static void main(String[]
args) {
String
source = "a\uD83D\uDE36b\uD83D\uDE36\uD83D\uDE36\uD83D\uDE36\uD83C\uDE3612312\uD83C\uDE36" ;
while ( true )
{
Integer
pos = source.indexOf( "\uD83D" );
if (pos
== - 1 )
{
pos
= source.indexOf( "\uD83C" );
}
if (pos
!= - 1 )
{
source
= source.substring( 0 ,
pos) + source.substring(pos + 2 );
} else {
break ;
}
}
System.out.println(source);
}
|