前面一篇有说道应用服务器和腾讯服务器是通过消息进行通讯的,并简单介绍了微信端post的消息类型,这里我们将建立消息实体以方便我们后面的使用!
(一)创建消息实体基础类
1 package com.gede.wechat.message.request; 2 /** 3 * @author gede 4 * @version date:2019年5月23日 下午6:36:31 5 * @description : 6 */ 7 public class BaseMessage { 8 // 开发者微信号 9 private String ToUserName; 10 // 发送方帐号(一个 OpenID) 11 private String FromUserName; 12 // 消息创建时间 (整型) 13 private long CreateTime; 14 // 消息类型(text/image/location/link/video/shortvideo) 15 private String MsgType; 16 // 消息 id,64 位整型 17 private long MsgId; 18 19 public String getToUserName() { 20 return ToUserName; 21 } 22 23 public void setToUserName(String toUserName) { 24 ToUserName = toUserName; 25 } 26 27 public String getFromUserName() { 28 return FromUserName; 29 } 30 31 public void setFromUserName(String fromUserName) { 32 FromUserName = fromUserName; 33 } 34 35 public long getCreateTime() { 36 return CreateTime; 37 } 38 39 public void setCreateTime(long createTime) { 40 CreateTime = createTime; 41 } 42 43 public String getMsgType() { 44 return MsgType; 45 } 46 47 public void setMsgType(String msgType) { 48 MsgType = msgType; 49 } 50 51 public long getMsgId() { 52 return MsgId; 53 } 54 55 public void setMsgId(long msgId) { 56 MsgId = msgId; 57 } 58 }
(二)创建普通消息pojo实体
①图片消息
1 package com.gede.wechat.message.request; 2 /** 3 * @author gede 4 * @version date:2019年5月23日 下午6:38:50 5 * @description : 6 */ 7 public class ImageMessage extends BaseMessage { 8 // 图片链接 9 private String PicUrl; 10 11 public String getPicUrl() { 12 return PicUrl; 13 } 14 15 public void setPicUrl(String picUrl) { 16 PicUrl = picUrl; 17 } 18 }
②链接消息
1 package com.gede.wechat.message.request; 2 /** 3 * @author gede 4 * @version date:2019年5月23日 下午6:39:07 5 * @description : 6 */ 7 public class LinkMessage extends BaseMessage { 8 // 消息标题 9 private String Title; 10 // 消息描述 11 private String Description; 12 // 消息链接 13 private String Url; 14 15 public String getTitle() { 16 return Title; 17 } 18 19 public void setTitle(String title) { 20 Title = title; 21 } 22 23 public String getDescription() { 24 return Description; 25 } 26 27 public void setDescription(String description) { 28 Description = description; 29 } 30 31 public String getUrl() { 32 return Url; 33 } 34 35 public void setUrl(String url) { 36 Url = url; 37 } 38 }
③地理位置消息
1 package com.gede.wechat.message.request; 2 /** 3 * @author gede 4 * @version date:2019年5月23日 下午6:39:18 5 * @description : 6 */ 7 public class LocationMessage extends BaseMessage { 8 // 地理位置维度 9 private String Location_X; 10 // 地理位置经度 11 private String Location_Y; 12 // 地图缩放大小 13 private String Scale; 14 // 地理位置信息 15 private String Label; 16 17 public String getLocation_X() { 18 return Location_X; 19 } 20 21 public void setLocation_X(String location_X) { 22 Location_X = location_X; 23 } 24 25 public String getLocation_Y() { 26 return Location_Y; 27 } 28 29 public void setLocation_Y(String location_Y) { 30 Location_Y = location_Y; 31 } 32 33 public String getScale() { 34 return Scale; 35 } 36 37 public void setScale(String scale) { 38 Scale = scale; 39 } 40 41 public String getLabel() { 42 return Label; 43 } 44 45 public void setLabel(String label) { 46 Label = label; 47 } 48 }
④文本消息
1 package com.gede.wechat.message.request; 2 /** 3 * @author gede 4 * @version date:2019年5月23日 下午6:39:32 5 * @description : 6 */ 7 public class TextMessage extends BaseMessage { 8 // 消息内容 9 private String Content; 10 11 public String getContent() { 12 return Content; 13 } 14 15 public void setContent(String content) { 16 Content = content; 17 } 18 }
⑤视频/小视屏消息
1 package com.gede.wechat.message.request; 2 3 /** 4 * @author gede 5 * @version date:2019年5月23日 下午6:40:46 6 * @description : 7 */ 8 public class VideoMessage extends BaseMessage { 9 10 private String MediaId; // 视频消息媒体 id,可以调用多媒体文件下载接口拉取数据 11 private String ThumbMediaId; // 视频消息缩略图的媒体 id,可以调用多媒体文件下载接口拉取数据 12 13 public String getMediaId() { 14 return MediaId; 15 } 16 17 public void setMediaId(String mediaId) { 18 MediaId = mediaId; 19 } 20 21 public String getThumbMediaId() { 22 return ThumbMediaId; 23 } 24 25 public void setThumbMediaId(String thumbMediaId) { 26 ThumbMediaId = thumbMediaId; 27 } 28 29 }
⑥语音消息
1 package com.gede.wechat.message.request; 2 /** 3 * @author gede 4 * @version date:2019年5月23日 下午6:41:02 5 * @description : 6 */ 7 public class VoiceMessage extends BaseMessage { 8 // 媒体 ID 9 private String MediaId; 10 // 语音格式 11 private String Format; 12 13 public String getMediaId() { 14 return MediaId; 15 } 16 17 public void setMediaId(String mediaId) { 18 MediaId = mediaId; 19 } 20 21 public String getFormat() { 22 return Format; 23 } 24 25 public void setFormat(String format) { 26 Format = format; 27 } 28 }
(三)消息分类处理
按照上面收到想消息类别分别做不同的分发处理,这里我们建立了自己的业务分发器(EventDispatcher、MsgDispatcher),分别做普通消息处理和事件消息处理!
①MsgDispatcher.java——用于普通消息的业务分发处理
1 package com.gede.wechat.dispatcher; 2 3 import java.util.Map; 4 5 import com.gede.wechat.util.MessageUtil; 6 7 /** 8 * @author gede 9 * @version date:2019年5月23日 下午6:49:11 10 * @description : 11 */ 12 public class MsgDispatcher { 13 public static String processMessage(Map<String, String> map) { 14 if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { // 文本消息 15 System.out.println("==============这是文本消息!"); 16 } 17 if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) { // 图片消息 18 System.out.println("==============这是图片消息!"); 19 } 20 if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) { // 链接消息 21 System.out.println("==============这是链接消息!"); 22 } 23 if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) { // 位置消息 24 System.out.println("==============这是位置消息!"); 25 } 26 if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) { // 视频消息 27 System.out.println("==============这是视频消息!"); 28 } 29 if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) { // 语音消息 30 System.out.println("==============这是语音消息!"); 31 } 32 33 return null; 34 } 35 }
②EventDispatcher.java——事件消息的业务分发处理
1 package com.gede.wechat.dispatcher; 2 3 import java.util.Map; 4 5 import com.gede.wechat.util.MessageUtil; 6 7 /** 8 * @author gede 9 * @version date:2019年5月23日 下午6:49:59 10 * @description : 11 */ 12 public class EventDispatcher { 13 public static String processEvent(Map<String, String> map) { 14 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { // 关注事件 15 System.out.println("==============这是关注事件!"); 16 } 17 18 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { // 取消关注事件 19 System.out.println("==============这是取消关注事件!"); 20 } 21 22 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_SCAN)) { // 扫描二维码事件 23 System.out.println("==============这是扫描二维码事件!"); 24 } 25 26 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_LOCATION)) { // 位置上报事件 27 System.out.println("==============这是位置上报事件!"); 28 } 29 30 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_CLICK)) { // 自定义菜单点击事件 31 System.out.println("==============这是自定义菜单点击事件!"); 32 } 33 34 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_VIEW)) { // 自定义菜单View事件 35 System.out.println("==============这是自定义菜单View事件!"); 36 } 37 38 return null; 39 } 40 }
这个时候我们需要把我们的消息入口【WechatSecurity.java】中的post方法做些修改,最终结果如下:
1 package com.gede.wechat.controller; 2 3 import java.io.PrintWriter; 4 import java.util.Map; 5 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import org.apache.log4j.Logger; 10 import org.springframework.stereotype.Controller; 11 import org.springframework.web.bind.annotation.RequestMapping; 12 import org.springframework.web.bind.annotation.RequestMethod; 13 import org.springframework.web.bind.annotation.RequestParam; 14 15 import com.gede.wechat.dispatcher.EventDispatcher; 16 import com.gede.wechat.dispatcher.MsgDispatcher; 17 import com.gede.wechat.util.MessageUtil; 18 import com.gede.wechat.util.SignUtil; 19 20 /** 21 * @author gede 22 * @version date:2019年5月22日 下午2:53:46 23 * @description : 24 */ 25 @Controller 26 @RequestMapping("/wechat") 27 public class WechatSecurity { 28 private static Logger logger = Logger.getLogger(WechatSecurity.class); 29 30 @RequestMapping(value = "security", method = RequestMethod.GET) 31 public void doGet( 32 HttpServletRequest request, 33 HttpServletResponse response, 34 @RequestParam(value = "signature", required = true) String signature, 35 @RequestParam(value = "timestamp", required = true) String timestamp, 36 @RequestParam(value = "nonce", required = true) String nonce, 37 @RequestParam(value = "echostr", required = true) String echostr) { 38 try { 39 if (SignUtil.checkSignature(signature, timestamp, nonce)) { 40 PrintWriter out = response.getWriter(); 41 out.print(echostr); 42 out.close(); 43 } else { 44 logger.info("这里存在非法请求!"); 45 } 46 } catch (Exception e) { 47 logger.error(e, e); 48 } 49 } 50 51 /** 52 * @Description: 接收微信端消息处理并做分发 53 * @param @param request 54 * @param @param response 55 * @author dapengniao 56 * @date 2016年3月7日 下午4:06:47 57 */ 58 @RequestMapping(value = "security", method = RequestMethod.POST) 59 public void DoPost(HttpServletRequest request,HttpServletResponse response) { 60 try{ 61 Map<String, String> map=MessageUtil.parseXml(request); 62 String msgtype=map.get("MsgType"); 63 if(MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgtype)){ 64 EventDispatcher.processEvent(map); //进入事件处理 65 }else{ 66 MsgDispatcher.processMessage(map); //进入消息处理 67 } 68 }catch(Exception e){ 69 logger.error(e,e); 70 } 71 } 72 }
最后我们运行成功项目之后我们可以通过发送不同类型的消息来验证我们的消息分类的正确性,如下图所示:
新建了这么多文件,最后来看下我们的整个项目的目录结构: