微信公号开发之文本消息技巧:长度限制、换行和表情

微信公众账号文本消息的内容长度限制揭秘

相信不少朋友都遇到过这样的问题:当发送的文本消息内容过长时,微信将不做任何响应。那么到底微信允许的文本消息的最大长度是多少呢?我们又该如何计算文本的长度呢?为什么还有些人反应微信好像支持的文本消息最大长度在1300多呢?这篇文章会彻底解除大家的疑问。

接口文档中对消息长度限制为2048:

可以看到,接口文档中写的很明确:回复的消息内容长度不超过2048字节。那为什么很多人测试反应消息内容长度在1300多字节时,微信就不响应了呢?我想这问题应该在这部分人没有搞清楚到底该如何计算文本的字节数。

如何正确计算文本所占字节数

计算文本(字符串)所占字节数,大家第一个想到的应该就是String类的getBytes()方法,该方法返回的是字符串对应的字节数组,再计算数组的length就能够得到字符串所占字节数。例如:

  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编码方式呢?我们再来看一个例子:

  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编码方式时,一个中文占三个字节。

微信平台采用的编码方式及字符串所占字节数的计算

那么,在向微信服务器返回消息时,该采用什么编码方式呢?当然是UTF-8,因为我们已经在doPost方法里采用了如下代码来避免中文乱码了:

  1. // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
  2. request.setCharacterEncoding("UTF-8");
  3. response.setCharacterEncoding("UTF-8");

getMsgContent()方法返回的内容正是微信的文本消息最长能够支持的,即采用UTF-8编码方式时,文本消息内容最多支持2047个字节,也就是微信公众平台接口文档里所说的回复的消息内容长度不超过2048字节,即使是等于2048字节也不行,你可以试着将getMsgContent()方法里的内容多加一个英文符号,这个时候微信就不响应了。

同时,我们也发现,如果采用gb2312编码方式来计算getMsgContent()方法返回的文本所占字节数的结果是1365,这就是为什么很 多朋友都说微信的文本消息最大长度好像只支持1300多字节,并不是接口文档中所说的2048字节,其实是忽略了编码方式,只是简单的使用了String 类的getBytes()方法而不是getBytes("utf-8")方法去计算所占字节数。

Java中utf-8编码方式时所占字节数的计算方法封装

  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. }

文本消息中换行符的使用

使用换行的好处及示例

使用换行的好处无非就是让信息的呈现更加整齐、美观和直观,适当的在文本消息中使用换行符,会让人看了之后感觉很舒服、清晰、明了。下面是公众帐号xiaoqrobot的主菜单示例,就是合理地使用了换行符,看上去是不是很直观、清爽呢?

如何在文本消息中使用换行符?

在微信公众帐号的文本消息中,换行符仍然是“\n”,下面就通过代码来讲解xiaoqrobot的文本菜单是如何实现的?

  1. /**
  2. * xiaoqrobot的主菜单
  3. *
  4. * @return
  5. */
  6. public static String getMainMenu() {
  7. StringBuffer buffer = new StringBuffer();
  8. buffer.append("您好,我是小q,请回复数字选择服务:").append("\n\n");
  9. buffer.append("1  天气预报").append("\n");
  10. buffer.append("2  公交查询").append("\n");
  11. buffer.append("3  周边搜索").append("\n");
  12. buffer.append("4  歌曲点播").append("\n");
  13. buffer.append("5  经典游戏").append("\n");
  14. buffer.append("6  美女电台").append("\n");
  15. buffer.append("7  人脸识别").append("\n");
  16. buffer.append("8  聊天唠嗑").append("\n\n");
  17. buffer.append("回复“?”显示此帮助菜单");
  18. return buffer.toString();
  19. }

怎么样,实现起来是不是很简单呢?

1)9-16行就是菜单项,菜单项之间都是用一个换行符分隔;

2)第8行、第16号末尾都使用了两个换行符,这样可以把菜单项与其他内容分隔开,更有层次感,看上去也会舒服、直观一点。

QQ表情的发送与接收

我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜、怒、哀、乐等表达人物心情的小图片。本文重点要介绍的内容就是如何在微信公众平台使用QQ表情,即在微信公众帐号开发模式下,如何发送QQ表情给用户,以及如何识别用户发来的是QQ表情。

QQ表情代码表

首先需要明确的是:QQ表情虽然呈现为一张张动态的表情图片,但在微信公众平台的消息接口中却是属于文本消息;也就是说当用户向公众帐号发送QQ表情时,公众帐号后台程序接收到的消息类型MsgType的值为text。只要上面这点能理解了,下面的工作就好开展了。

对于QQ表情,发送的是文本消息,而呈现出来却是表情图片,那么每一个QQ表情图片一定会有与之相对应的表情代码。下面是我已经整理好的微信公众帐号中使用的QQ表情代码对照表:

上面一共列出了105个QQ表情,每个表情都给出了与之相对应的文字代码与符号代码(也许这两种叫法并不恰当),至于这两种代码怎么来的以及如何使用,下面马上会讲到。

用户向公众帐号发送QQ表情

在微信上使用公众帐号时,如何发送QQ表情,我想这个很少有人不会的。在输入框旁边有一个笑脸的图片按钮,点击它将会弹出表情选择界面,可选择的表情依次为“QQ表情”、“符号表情”和“动画表情”。当我们点击选择了某个QQ表情后,发现在输入框中会显示该表情的文字代码,这里是用一对中括号引起的,如下图所示:

其实,当我们很熟悉要使用QQ表情的文字代码时,也可以直接在输入框中输入表情的代码,而不需要弹出表情选择框。如下图所示:

从上图可以看出,在输入框中输入“[呲牙]”、“/呲牙”和“/::D”这三种代码的作用一样,都是发送呲牙的QQ表情。这个时候,大家再回过头去看文章最开始的QQ表情代码对照表,就明白是怎么回事了。

公众帐号向用户发送QQ表情

与用户向公众帐号发送QQ表情一样,在开发模式下,公众帐号也可以用同样的表情代码(文字代码或符号代码)向用户回复QQ表情。代码片段如下:

  1. // 文本消息
  2. if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
  3. // 回复文本消息
  4. TextMessage textMessage = new TextMessage();
  5. textMessage.setToUserName(fromUserName);
  6. textMessage.setFromUserName(toUserName);
  7. textMessage.setCreateTime(new Date().getTime());
  8. textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
  9. textMessage.setFuncFlag(0);
  10. textMessage.setContent("[难过] /难过 /::(");
  11. // 文本消息对象转换成xml字符串
  12. respMessage = MessageUtil.textMessageToXml(textMessage);
  13. }

上面代码片段的作用是:判断发送的消息类型,如果是文本消息(MsgType=text),则回复三个难过的QQ表情给用户。可以看出,不管是用户发给公众帐号,还是公众帐号发给用户,都可以使用QQ表情的文字代码(如:[难过]  /难过)和符号代码(如 /::()。

公众帐号识别用户发送的QQ表情

在掌握了如何发送QQ表情后,我们再来看看公众帐号如何识别用户发送的是QQ表情。这是什么意思呢?当用户向公众帐号发送一个QQ表情,在后台程序中接收到的会是什么值,我们又怎么知道这个值就是一个QQ表情。

其实,只要做个简单的测试,比如:将接收到的文本消息输出到日志中(可以用log4j或者System.out.print),不难发现:向公众帐号发送一个QQ表情,在后台程序中接收到的是QQ表情的符号代码。

下面是我简单封装的一个方法,通过正则表达式实现的,用于判断用户发送的是否是单个QQ表情。

  1. /**
  2. * 判断是否是QQ表情
  3. *
  4. * @param content
  5. * @return
  6. */
  7. public static boolean isQqFace(String content) {
  8. boolean result = false;
  9. // 判断QQ表情的正则表达式
  10. String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::‘\\(|/::-\\||/::@|/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::‘\\||/:X-\\)|/::\\*|/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>";
  11. Pattern p = Pattern.compile(qqfaceRegex);
  12. Matcher m = p.matcher(content);
  13. if (m.matches()) {
  14. result = true;
  15. }
  16. return result;
  17. }

下面是方法的使用,实现了这样一个简单的功能:用户发什么QQ表情给公众帐号,公众帐号就回复什么QQ表情给用户(xiaoqrobot就是这么做的)。实现代码如下:

  1. // 文本消息
  2. if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
  3. // 文本消息内容
  4. String content = requestMap.get("Content");
  5. // 判断用户发送的是否是单个QQ表情
  6. if(XiaoqUtil.isQqFace(content)) {
  7. // 回复文本消息
  8. TextMessage textMessage = new TextMessage();
  9. textMessage.setToUserName(fromUserName);
  10. textMessage.setFromUserName(toUserName);
  11. textMessage.setCreateTime(new Date().getTime());
  12. textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
  13. textMessage.setFuncFlag(0);
  14. // 用户发什么QQ表情,就返回什么QQ表情
  15. textMessage.setContent(content);
  16. // 将文本消息对象转换成xml字符串
  17. respMessage = MessageUtil.textMessageToXml(textMessage);
  18. }
  19. }

好了,关于微信公众帐号中QQ表情的使用就介绍这么多。其实,我并不希望初学者上来只是简单拷贝我贴出的代码,实现了自己想要的功能就完事了,更希望初学的朋友能够通过此文章学会一种思考问题和解决问题的方法。

http://mobile.51cto.com/web-416967_all.htm

时间: 2024-10-09 21:56:40

微信公号开发之文本消息技巧:长度限制、换行和表情的相关文章

微信公众号开发之文本消息自动回复,以及系统关注自动回复,php代码

以tshop为例 直接上代码: 企业 cc_wx_sys表为自建,存储系统消息的配置的 字段: id type key status <?php /** * tpshop * ============================================================================ * * 版权所有 2015-2027 深圳搜豹网络科技有限公司,并保留所有权利. * 网站地址: http://www.tp-shop.cn * ------------

微信公众号开发之自动消息回复和自定义菜单

(一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 前言 上一篇我们大致讲解了下微信公众号开发的基本原理和流程概述.本章主要是对文本消息回复和自定义菜单做一个记录和分解 消息回复 处理请求,并响应 1)关注 也可参考官网文档:https://mp.weixin.qq.com/wiki 当微信用户关注公众账号时,可以给其适当的提示.可以是欢迎词,可以是帮助提示.示例代码如下: class EventHandler : IHandler

微信公众号开发教程[003]-消息管理-接收消息

当微信用户向公众号发送消息时,微信服务器会向公众号配置的服务器URL地址发送请求,并将相关内容包装成一定格式的xml发送到这个服务器;响应时,这个服务器只要回复特定格式的xml字符串给微信服务器,微信服务器即可向微信用户的客户端转发这条回复消息.(假设公众号开发模式已开启,以后的教程,如果没有特别说明,都是如此).如下图: 例如,文本消息的xml结构如下: <xml> <ToUserName><![CDATA[toUser]]></ToUserName> &

Java微信公众号开发----关键字自动回复消息

在配置好开发者配置后,本人第一个想要实现的是自动回复消息的功能,说明以下几点: 1. url 仍然不变,还是开发配置里的url 2. 微信采用 xml 格式传输数据 3.微信服务器传给我们的参数主要有(如图): 附上解析xml类的依赖: 1 <!-- dom对象读取写入xml文件 --> 2 <dependency> 3 <groupId>dom4j</groupId> 4 <artifactId>dom4j</artifactId>

微信公众号开发之语音消息识别

1.开通语音识别(默认关闭) 2.语音识别 请注意,开通语音识别后,用户每次发送语音给公众号时,微信会在推送的语音消息XML数据包中,增加一个Recognition字段(注:由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注用户需要24小时生效.开发者可以重新关注此帐号进行测试).开启语音识别后的语音XML数据包如下: 1 <?php 2 /** 3 * wechat php test 4 */ 5 6 //define your token 7 define("

微信公众号开发教程[005]-消息管理-消息加解密

一.配置公众号消息加解密方式 在公众号官方管理后台->开发->基本配置->修改配置上有3种方式,如下: 其中,EncodingAESKey可以随机生成. 加解密方式说明: 1).明文模式:微信服务器向公众号服务器(即我们要处理的http://szuzsq.tunnel.qydev.com/weixin/index.php)发送的xml结构是原始的,没有加密.如下: <xml> <ToUserName><![CDATA[gh_733c42e0aee9]]>

微信公众号开发java版-消息回复(普通文字消息和语音消息)

关于微信公众号的消息自动回复功能开发,本文将做一个系统介绍,开发语言为java 话不多说,直接上代码 1.控制器代码 package webapp.controller; import org.springframework.context.annotation.Scope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.R

C#微信公众号开发之模板消息开发,附源码

个人觉得模板消息功能的增加对公众号的作用非常大,可以说是真正意义上的实现了所谓的轻app,商家可以通过模板消息给用户发送重要的信息,交易.预约.消费.邮件.物流等信息.之前我做过的系统通过邮件发送订单消息,但是对于一些不喜欢绑定手机邮箱(实时提现商家发货买家订单进程等)的人来说还是不够方便,有了模板消息,公众号得以独立的完成交易信息通知跟踪等. 开发文档:http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html C

微信公众号开发之群发消息

图文群发消息流程 1.上传图片缩略图获取media_id 2.上传图文素材获取图文素材的media_id 3.群发消息 这里给出了图文群发的预览接口和群发接口 //图文群发 public function tuwenqunfa(){ $accessTokenInfo = file_get_contents("access_token.log"); if($accessTokenInfo){ $tokenArr = json_decode($accessTokenInfo,true);