[030] 微信公眾帳號開發教程第6篇-文本消息的內容長度限制揭秘(轉)


相信不少朋友都遇到過這種問題:當發送的文本消息內容過長時,微信將不做不論什么響應。那么究竟微信同意的文本消息的最大長度是多少呢?我們又該怎樣計算文本的長度呢?為什么還有些人反應微信好像支持的文本消息最大長度在1300多呢?這篇文章會徹底解除大家的疑問。

 

接口文檔中對消息長度限制為2048

以看到,接口文檔中寫的非常明白:回復的消息內容長度不超過2048字節。那為什么非常多人測試反應消息內容長度在1300多字節時,微信就不響應了呢?我想這問題應該在這部分人沒有搞清晰究竟該怎樣計算文本的字節數。

 

怎樣正確計算文本所占字節數

計算文本(字符串)所占字節數,大家第一個想到的應該就是String類的getBytes()方法,該方法返回的是字符串相應的字節數組,再計算數組的length就行得到字符串所占字節數。比如:

 

[java]  view plain copy
 
  1. public static void main(String []args)  {  
  2.     // 執行結果:4  
  3.     System.out.println("柳峰".getBytes().length);  
  4. }  

上面的演示例子中計算了兩個中文所占的字節數為4,即一個漢字占2個字節。真的是這樣嗎?事實上我們忽略了一個問題:對於不同的編碼方式,中文所占的字節數也不一樣!這究竟要怎么呢?在上面的樣例中,我們並沒有指定編碼方式,那么會使用操作系統所默認的編碼方式。先來看我得出的三條結論:

 

1)假設上面的樣例執行在默認編碼方式為ISO8859-1的操作系統平台上,計算結果是2;

2)假設上面的樣例執行在默認編碼方式為gb2312或gbk的操作系統平台上,計算結果是4;

3)假設上面的樣例執行在默認編碼方式為utf-8的操作系統平台上,計算結果是6;

假設真的是這樣,是不是意味着String.getBytes()方法在我們的系統平台上默認採用的是gb2312或gbk編碼方式呢?我們再來看一個樣例:

 

[java]  view plain copy
 
  1. public static void main(String []args) throws UnsupportedEncodingException  {  
  2.     // 執行結果:2  
  3.     System.out.println("柳峰".getBytes("ISO8859-1").length);  
  4.     // 執行結果:4  
  5.     System.out.println("柳峰".getBytes("GB2312").length);  
  6.     // 執行結果:4  
  7.     System.out.println("柳峰".getBytes("GBK").length);  
  8.     // 執行結果:6  
  9.     System.out.println("柳峰".getBytes("UTF-8").length);  
  10. }  

這個樣例是不是非常好地證明了我上面給出的三條結論呢?也就是說採用ISO8859-1編碼方式時,一個中/英文都僅僅占一個字節;採用GB2312或GBK編碼方式時,一個中文占兩個字節;而採用UTF-8編碼方式時,一個中文占三個字節。

 

 

微信平台採用的編碼方式及字符串所占字節數的計算

那么,在向微信server返回消息時,該採用什么編碼方式呢?當然是UTF-8,由於我們已經在doPost方法里採用了例如以下代碼來避免中文亂碼了:

 

[java]  view plain copy
 
  1. // 將請求、響應的編碼均設置為UTF-8(防止中文亂碼)  
  2. request.setCharacterEncoding("UTF-8");  
  3. response.setCharacterEncoding("UTF-8");  

為了驗證我所說了,我寫了個樣例來測試:

 

 

[java]  view plain copy
 
  1. private static String getMsgContent() {  
  2.     StringBuffer buffer = new StringBuffer();  
  3.     // 每行70個漢字,共682個漢字加1個英文的感嘆號  
  4.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  5.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  6.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  7.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  8.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  9.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  10.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  11.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  12.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽你的手走過風風雨雨有什么困難我都陪你");  
  13.     buffer.append("不知道什么時候開始喜歡這里每一個夜里都會來這里看你你長得多么漂亮叫我不能不看你看不到你我就迷失了自己好想牽!");  
  14.     return buffer.toString();  
  15. }  
  16.   
  17. public static void main(String []args) throws Exception  {  
  18.     // 採用gb2312編碼方式時占1365個字節  
  19.     System.out.println(getMsgContent().getBytes("gb2312").length);  
  20.     // 採用utf-8編碼方式時占2047個字節  
  21.     System.out.println(getMsgContent().getBytes("utf-8").length);  
  22. }  

getMsgContent()方法返回的內容正是微信的文本消息最長可以支持的,即採用UTF-8編碼方式時,文本消息內容最多支持2047個字節,也就是微信公眾平台接口文檔里所說的回復的消息內容長度不超過2048字節,即使是等於2048字節也不行,你可以試着將getMsgContent()方法里的內容多加一個英文符號,這個時候微信就不響應了。

同一時候,我們也發現,假設採用gb2312編碼方式來計算getMsgContent()方法返回的文本所占字節數的結果是1365,這就是為什么非常多朋友都說微信的文本消息最大長度好像僅僅支持1300多字節,並非接口文檔中所說的2048字節,事實上是忽略了編碼方式,僅僅是簡單的使用了String類的getBytes()方法而不是getBytes("utf-8")方法去計算所占字節數。

 

Java中utf-8編碼方式時所占字節數的計算方法封裝

 

[java]  view plain copy
 
  1. /** 
  2.  * 計算採用utf-8編碼方式時字符串所占字節數 
  3.  *  
  4.  * @param content 
  5.  * @return 
  6.  */  
  7. public static int getByteSize(String content) {  
  8.     int size = 0;  
  9.     if (null != content) {  
  10.         try {  
  11.             // 漢字採用utf-8編碼時占3個字節  
  12.             size = content.getBytes("utf-8").length;  
  13.         } catch (UnsupportedEncodingException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.     }  
  17.     return size;  
  18. }  

 

好了,本章節的內容就說到這里,我想大家通過這篇文章所學到的應該不僅僅是2047這個數字,還應該對字符編碼方式有一個新的認識。

 

假設認為文章對你有所幫助,請留言支持或關注微信公眾帳號xiaoqrobot支持柳峰哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM