由于作者曾经在学习微信开发之初曾经参考过好多大神的技术博客,代码逻辑难免会有雷同,望见谅!
为了初学者,还是把前几章节的消息流转的流程图贴上来如下:
描述:消息其实是由用户发给你的公众帐号的,消息先被微信平台接收到,然后微信平台会将该消息转给你在开发模式接口配置中指定的URL地址上。
微信公众平台管理中心-消息管理接口
要接收微信平台发送的消息,我们需要先熟悉微信公众平台API中消息接口部分,登录微信公众开发者平台中心,查看接口权限-消息管理接口,如下图:
在上图左侧我们可以看到,消息管理其实分为两种 ,一种是接收用户发来的消息,一种是回复用户消息。
接收消息和发送消息
接收消息指的是“当普通用户向公众帐号发消息时,微信服务器将POST该消息到填写的URL上”,即这里定义的是用户能够发送哪些类型的消息、消息有哪些字段、消息被微信服务器以什么方式转发给我们的公众帐号后台。
接收消息
当普通用户向公众帐号发消息时,微信服务器将POST该消息到填写的URL上
消息推送中定义了我们将会接收到的消息类型有7种:文本消息、图片消息、地理位置消息、链接消息,语音消息,视频消息和小视频消息。
发送消息
发送消息指的是用户发送消息后微信响应给用户的消息,例如,A用户向公众号发送一条B消息,公众号响应一条C消息,而这条C消息便叫做公众号的发送消息。
目前发送消息支持6种类型的消息
1 回复文本消息2 回复图片消息3 回复语音消息4 回复视频消息5 回复音乐消息6 回复图文消息
当然回复用户的消息也是通过servlet的post方法post发送给用户的。
消息的封装
接下来要做的就是将消息推送(请求)、消息回复(响应)中定义的消息进行封装,建立与之对应的Java类,下面的请求消息是指消息推送中定义的消息,响应消息指消息回复中定义的消息。
请求消息的基类
把消息推送中定义的所有消息都有的字段提取出来,封装成一个基类,这些公有的字段包括:ToUserName(开发者微信号)、FromUserName(发送方帐号,OPEN_ID)、CreateTime(消息的创建时间)、MsgType(消息类型)、MsgId(消息ID),封装后基类,基类BaseMessage代码如下:
package com.test.message.req; /** * 消息基类(普通用户 -> 公众帐号) * V型知识库 www.vxzsk.com */ public class BaseMessage { // 开发者微信号 private String ToUserName; // 发送方帐号(一个OpenID) private String FromUserName; // 消息创建时间 (整型) private long CreateTime; // 消息类型(text/image/location/link) private String MsgType; // 消息id,64位整型 private long MsgId; public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } public long getMsgId() { return MsgId; } public void setMsgId(long msgId) { MsgId = msgId; } }
接收消息文本消息类
package com.test.message.resp; /** * 文本消息 * V型知识库 www.vxzsk.com */ public class TextMessage extends BaseMessage { // 回复的消息内容 private String Content; public String getContent() { return Content; } public void setContent(String content) { Content = content; } }
接收消息 图片消息类
package com.test.message.req; /** * 图片消息 * V型知识库 www.vxzsk.com */ public class ImageMessage extends BaseMessage { // 图片链接 private String PicUrl; public String getPicUrl() { return PicUrl; } public void setPicUrl(String picUrl) { PicUrl = picUrl; } }
接收消息-地理位置消息类
package com.test.message.req; /** * 地理位置消息 * V型知识库 www.vxzsk.com */ public class LocationMessage extends BaseMessage { // 地理位置维度 private String Location_X; // 地理位置经度 private String Location_Y; // 地图缩放大小 private String Scale; // 地理位置信息 private String Label; public String getLocation_X() { return Location_X; } public void setLocation_X(String location_X) { Location_X = location_X; } public String getLocation_Y() { return Location_Y; } public void setLocation_Y(String location_Y) { Location_Y = location_Y; } public String getScale() { return Scale; } public void setScale(String scale) { Scale = scale; } public String getLabel() { return Label; } public void setLabel(String label) { Label = label; } }
接收消息-链接消息类
package com.test.message.req; /** * 链接消息 * * V型知识库 www.vxzsk.com */ public class LinkMessage extends BaseMessage { // 消息标题 private String Title; // 消息描述 private String Description; // 消息链接 private String Url; public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return Description; } public void setDescription(String description) { Description = description; } public String getUrl() { return Url; } public void setUrl(String url) { Url = url; } }
接收消息语音消息类
package com.test.message.req; /** * 音频消息 * * V型知识库 www.vxzsk.com */ public class VoiceMessage extends BaseMessage { // 媒体ID private String MediaId; // 语音格式 private String Format; public String getMediaId() { return MediaId; } public void setMediaId(String mediaId) { MediaId = mediaId; } public String getFormat() { return Format; } public void setFormat(String format) { Format = format; } }
视频消息类在这里没写,下次有机会补上或者读者可根据上述类自行编写
发送消息-被动回复消息的基类
同样,把消息回复中定义的所有消息都有的字段提取出来,封装成一个基类,这些公有的字段包括:ToUserName(接收方帐号,用户的OPEN_ID)、FromUserName(开发者的微信号)、CreateTime(消息的创建时间)、MsgType(消息类型)、FuncFlag(消息的星标标识),封装后基类
package com.test.message.resp; /** * 消息基类(公众帐号 -> 普通用户) * V型知识库 www.vxzsk.com */ public class BaseMessage { // 接收方帐号(收到的OpenID) private String ToUserName; // 开发者微信号 private String FromUserName; // 消息创建时间 (整型) private long CreateTime; // 消息类型(text/music/news) private String MsgType; // 位0x0001被标志时,星标刚收到的消息 private int FuncFlag; public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } public int getFuncFlag() { return FuncFlag; } public void setFuncFlag(int funcFlag) { FuncFlag = funcFlag; } }
回复文本消息
package com.test.message.resp; /** * 文本消息 * v型知识库 www.vxzsk.com */ public class TextMessage extends BaseMessage { // 回复的消息内容 private String Content; public String getContent() { return Content; } public void setContent(String content) { Content = content; } }
音乐消息基类
package com.test.message.resp; /** * 音乐消息 * V型知识库 www.vxzsk.com */ public class MusicMessage extends BaseMessage { // 音乐 private Music Music; public Music getMusic() { return Music; } public void setMusic(Music music) { Music = music; } }
音乐model
package com.test.message.resp; /** * 音乐model */ public class Music { // 音乐名称 private String Title; // 音乐描述 private String Description; // 音乐链接 private String MusicUrl; // 高质量音乐链接,WIFI环境优先使用该链接播放音乐 private String HQMusicUrl; public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return Description; } public void setDescription(String description) { Description = description; } public String getMusicUrl() { return MusicUrl; } public void setMusicUrl(String musicUrl) { MusicUrl = musicUrl; } public String getHQMusicUrl() { return HQMusicUrl; } public void setHQMusicUrl(String musicUrl) { HQMusicUrl = musicUrl; } }
图文消息类
package com.test.message.resp; import java.util.List; /** * 图文消息 * V型知识库 www.vxzsk.com */ public class NewsMessage extends BaseMessage { // 图文消息个数,限制为10条以内 private int ArticleCount; // 多条图文消息信息,默认第一个item为大图 private List<Article> Articles; public int getArticleCount() { return ArticleCount; } public void setArticleCount(int articleCount) { ArticleCount = articleCount; } public List<Article> getArticles() { return Articles; } public void setArticles(List<Article> articles) { Articles = articles; } }
根据微信官方文档发送图文消息的XML格式 有articles节点,在这里也有个描述此节点的类
package com.test.message.resp; /** * 图文model * V型知识库 www.vxzsk.com */ public class Article { // 图文消息名称 private String Title; // 图文消息描述 private String Description; // 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80,限制图片链接的域名需要与开发者填写的基本资料中的Url一致 private String PicUrl; // 点击图文消息跳转链接 private String Url; public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return null == Description ? "" : Description; } public void setDescription(String description) { Description = description; } public String getPicUrl() { return null == PicUrl ? "" : PicUrl; } public void setPicUrl(String picUrl) { PicUrl = picUrl; } public String getUrl() { return null == Url ? "" : Url; } public void setUrl(String url) { Url = url; } }
全部封装后IDE工具中的代码结构如下:
如何接收消息发送消息?
其实用户关注公众号后发送消息,我们的后端服务器java代码在配置的url中的servlet的dopost方法中接收用户发来的消息,并且在doPOST方法中发送响应消息返回给用户。请看我们的doPOST方法
/** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("V型知识库原创www.vxzsk.com"); System.out.println("微信服务器发来消息------------"); // 将请求、响应的编码均设置为UTF-8(防止中文乱码) request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); try{ //xml请求解析 Map<String, String> requestMap = MessageUtil.parseXml(request);//接收微信发过来的xml格式 //发送方帐号(open_id) String fromUserName = requestMap.get("FromUserName"); //公众帐号 String toUserName = requestMap.get("ToUserName");
doPOST方法中有个解析XML格式的工具类MessageUtil,代码如下
package com.test.util; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /*** * * @author V型知识库 www.vxzsk.com * * */ public class MessageUtil { /** * 解析微信发来的请求(XML) * * @param request * @return * @throws Exception */ @SuppressWarnings("unchecked") public static Map<String, String> parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) { map.put(e.getName(), e.getText()); } // 释放资源 inputStream.close(); inputStream = null; return map; } }
MessageUtil工具类中只有一个解析用户发来的消息微信服务器封装成XML发送到我们的doPOST中,那么我们怎么把想要发送给用户的消息封装成XML格式给微信服务器,微信服务器解析并发送给用户呢?由于字数限制我们在下一章节贴出剩下的代码。
感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程