乐趣区

微信消息推送之过长的文本消息拆分踩坑

场景提出

故事要从微信消息推送说起,因为微信对文本消息的推送限定字节数为 2048 个,多出来的直接被砍掉。所以就想要对过长的文本消息进行拆分。

起初想的是用字节数据拆分,但是发现用字节数组拆分,会出现消息转化乱码的问题,原因其实也很好理解,因为不同字符占用的字节数不一样,所以简单的拆分又重新转换为 String,就会出现将本来一个字符的上半个字节转换为一个字符,下半个字节转换为一个字符,这样就出现了乱码。

因此,我决定按字符去拆分,但是按字符去拆分:(最终 pageSize 取 600)

代码示例

拆分方法(代码片段):

public List splitMessageByChars(String message,int pageSize) {

List messages = Lists.newArrayList();

char[] chars = message.toCharArray();

for (int i = 0;i

int j = i + pageSize;

String m ;

if (j>chars.length){

m = new String(chars,i,chars.length-i);

}else {

m = new String(chars,i,pageSize);

}

if (m.indexOf(‘\n’)==0){

messages.add(m.substring(1));

}else {

messages.add(m);

}

}

return messages;

}

可以看到代码中对 \n 做了过滤,原因是微信的文本消息推送,如果你首字符为 \n 的话就会报错,所以就需要对消息首字符为 \n 的情况做单独处理。

字节数占用的验证 (代码片段)
外汇经纪商对比 https://www.fx61.com/brokerlist

@Test

public void contextLoads() throws UnsupportedEncodingException {

List charsets = Lists.newArrayList();

charsets.add(StandardCharsets.UTF_8.name());

charsets.add(StandardCharsets.UTF_16.name());

charsets.add(StandardCharsets.UTF_16BE.name());

charsets.add(StandardCharsets.UTF_16LE.name());

charsets.add(StandardCharsets.ISO_8859_1.name());

charsets.add(StandardCharsets.US_ASCII.name());

charsets.add(“UTF-32”);

charsets.add(“GBK”);

charsets.add(“GB2312”);

charsets.add(“unicode”);

List ss = Lists.newArrayList();

ss.add(“ 测 ”);

ss.add(“a”);

ss.add(“aa”);

ss.add(“aaa”);

ss.add(“\n”);

ss.add(“\\”);

for (String s : ss){

// 字节测试

System.out.println(“———“+” 字符:\t”+s+”\t——-“);

for (String cs : charsets){

System.out.println(“ 在 ”+cs+” 编码下字节数为:”+s.getBytes(cs).length);

}

}

}

执行结果

——— 字符: 测 ——-

在 UTF- 8 编码下字节数为:3

在 UTF-16 编码下字节数为:4

在 UTF-16BE 编码下字节数为:2

在 UTF-16LE 编码下字节数为:2

在 ISO-8859- 1 编码下字节数为:1

在 US-ASCII 编码下字节数为:1

在 UTF-32 编码下字节数为:4

在 GBK 编码下字节数为:2

在 GB2312 编码下字节数为:2

在 unicode 编码下字节数为:4

——— 字符: a ——-

在 UTF- 8 编码下字节数为:1

在 UTF-16 编码下字节数为:4

在 UTF-16BE 编码下字节数为:2

在 UTF-16LE 编码下字节数为:2

在 ISO-8859- 1 编码下字节数为:1

在 US-ASCII 编码下字节数为:1

在 UTF-32 编码下字节数为:4

在 GBK 编码下字节数为:1

在 GB2312 编码下字节数为:1

在 unicode 编码下字节数为:4

——— 字符: aa ——-

在 UTF- 8 编码下字节数为:2

在 UTF-16 编码下字节数为:6

在 UTF-16BE 编码下字节数为:4

在 UTF-16LE 编码下字节数为:4

在 ISO-8859- 1 编码下字节数为:2

在 US-ASCII 编码下字节数为:2

在 UTF-32 编码下字节数为:8

在 GBK 编码下字节数为:2

在 GB2312 编码下字节数为:2

在 unicode 编码下字节数为:6

——— 字符: aaa ——-

在 UTF- 8 编码下字节数为:3

在 UTF-16 编码下字节数为:8

在 UTF-16BE 编码下字节数为:6

在 UTF-16LE 编码下字节数为:6

在 ISO-8859- 1 编码下字节数为:3

在 US-ASCII 编码下字节数为:3

在 UTF-32 编码下字节数为:12

在 GBK 编码下字节数为:3

在 GB2312 编码下字节数为:3

在 unicode 编码下字节数为:8

——— 字符:

——-

在 UTF- 8 编码下字节数为:1

在 UTF-16 编码下字节数为:4

在 UTF-16BE 编码下字节数为:2

在 UTF-16LE 编码下字节数为:2

在 ISO-8859- 1 编码下字节数为:1

在 US-ASCII 编码下字节数为:1

在 UTF-32 编码下字节数为:4

在 GBK 编码下字节数为:1

在 GB2312 编码下字节数为:1

在 unicode 编码下字节数为:4

——— 字符: \ ——-

在 UTF- 8 编码下字节数为:1

在 UTF-16 编码下字节数为:4

在 UTF-16BE 编码下字节数为:2

在 UTF-16LE 编码下字节数为:2

在 ISO-8859- 1 编码下字节数为:1

在 US-ASCII 编码下字节数为:1

在 UTF-32 编码下字节数为:4

在 GBK 编码下字节数为:1

在 GB2312 编码下字节数为:1

在 unicode 编码下字节数为:4

最后为简单结论

‘\n’是一个字符,占 1 个字节 汉字若是用 UTF- 8 编码,占 3 个字节,特别的汉字占用 4 个字节 汉字若是用 GBK 编码,占 2 个字节。

汉字若是用 UTF-16 编码,占 2 个字节,特别的汉字占用 4 个字节

字母若是用 UTF- 8 编码,占 1 个字节。

字母若是用 UTF-16 编码,占 2 个字节。(至于下面代码中,a 占 4 个,aa 占 6 个,aaa 占 8 个原因是,java 在其中)

字母若是用 UTF-32 编码,占 4 个字节。字母若是用 GBK 编码,占 1 个字节。字母若是用 GB2312 编码,占 1 个字节。

退出移动版