为了保证文章的完整独立性和可读性,我是新建了一个Java Project(Java web工程也可以,没有太大关系),没有在前几篇文章所讲到的weixinCourse工程中添加代码。如果需要,读者可以自己实现将菜单创建的代码移到自己已有的工程中去。
图中所有Java文件的源代码都在文章中贴出并进行了说明,图中使用到的jar也是Java开发中通用的jar包,很容易在网上下载到。
工程中引入的jar包主要分为两类:
1)第一类是json开发工具包,用于Java对象和Json字符串之间的转换;json开发工具包一共有3个jar:ezmorph-1.0.6.jar,json-lib-2.2.3-jdk13.jar和morph-1.1.1.jar。
2)第二类是slf4j日志工具包,用于记录系统运行所产生的日志,日志可以输出到控制台或文件中。
整个工程中,唯一没有讲到的是src下的log4j.properties的配置,也把它贴出来,方便大家参考,这样才是一个完整的工程源码。log4j.properties文件的内容如下:
log4j.rootLogger=info,console,file
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern='-'yyyy-MM-dd
log4j.appender.file.File=./logs/weixinmpmenu.log
log4j.appender.file.Append=true
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p] %d %37c %3x - %m%n
如何响应菜单点击事件
自定义菜单的创建工作已经完成,那么该如何接收和响应菜单的点击事件呢,也就是说在公众帐号后台处理程序中,如何识别用户点击的是哪个菜单,以及做出响应。这部分内容其实在教程的第5篇各种消息的接收与响应中已经讲解清楚了。
来看一下第一篇教程weixinCourse项目中的CoreService类要怎么改写,才能接收响应菜单点击事件,该类修改后的完整代码如下:
package org.liufeng.course.service; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.liufeng.course.message.resp.TextMessage; import org.liufeng.course.util.MessageUtil; /** * 核心服务类 * * @author liufeng * @date 2013-05-20 */ public class CoreService { /** * 处理微信发来的请求 * * @param request * @return */ public static String processRequest(HttpServletRequest request) { String respMessage = null; try { // 默认返回的文本消息内容 String respContent = "请求处理异常,请稍候尝试!"; // xml请求解析 Map requestMap = MessageUtil.parseXml(request); // 发送方帐号(open_id) String fromUserName = requestMap.get("FromUserName"); // 公众帐号 String toUserName = requestMap.get("ToUserName"); // 消息类型 String msgType = requestMap.get("MsgType"); // 回复文本消息 TextMessage textMessage = new TextMessage(); textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT); textMessage.setFuncFlag(0); // 文本消息 if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { respContent = "您发送的是文本消息!"; } // 图片消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) { respContent = "您发送的是图片消息!"; } // 地理位置消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) { respContent = "您发送的是地理位置消息!"; } // 链接消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) { respContent = "您发送的是链接消息!"; } // 音频消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) { respContent = "您发送的是音频消息!"; } // 事件推送 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) { // 事件类型 String eventType = requestMap.get("Event"); // 订阅 if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { respContent = "谢谢您的关注!"; } // 取消订阅 else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { // TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息 } // 自定义菜单点击事件 else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) { // 事件KEY值,与创建自定义菜单时指定的KEY值对应 String eventKey = requestMap.get("EventKey"); if (eventKey.equals("11")) { respContent = "天气预报菜单项被点击!"; } else if (eventKey.equals("12")) { respContent = "公交查询菜单项被点击!"; } else if (eventKey.equals("13")) { respContent = "周边搜索菜单项被点击!"; } else if (eventKey.equals("14")) { respContent = "历史上的今天菜单项被点击!"; } else if (eventKey.equals("21")) { respContent = "歌曲点播菜单项被点击!"; } else if (eventKey.equals("22")) { respContent = "经典游戏菜单项被点击!"; } else if (eventKey.equals("23")) { respContent = "美女电台菜单项被点击!"; } else if (eventKey.equals("24")) { respContent = "人脸识别菜单项被点击!"; } else if (eventKey.equals("25")) { respContent = "聊天唠嗑菜单项被点击!"; } else if (eventKey.equals("31")) { respContent = "Q友圈菜单项被点击!"; } else if (eventKey.equals("32")) { respContent = "电影排行榜菜单项被点击!"; } else if (eventKey.equals("33")) { respContent = "幽默笑话菜单项被点击!"; } } } textMessage.setContent(respContent); respMessage = MessageUtil.textMessageToXml(textMessage); } catch (Exception e) { e.printStackTrace(); } return respMessage; } }
代码说明:
1)第69行、第81行这两行代码说明了如何判断菜单的点击事件。当消息类型MsgType=event,并且Event=CLICK时,就表示是自定义菜单点击事件;
2)第83行是判断具体点击的是哪个菜单项,根据菜单的key值来判断;
3)第85~109行表示当用户点击某个菜单项后,具体返回什么消息,我只是做个简单示例,统一返回文本消息,读者可以根据实际需要来灵活处理。
总结