微信公众帐号开发教程第6篇-消息及消息处理工具的封装
本篇内容主要讲解如何将微信公众平台定义的消息及消息相关的操作封装成工具类,方面后期的使用 官方文档
接下来要做的就是将消息请求、回复中定义的消息进行封装,建立与之对应的Java类(Java是一门面向对象的编程语言,封装后使用起来更方便),下面的请求消息是指消息推送中定义的消息,响应消息指消息回复中定义的消息。
消息的基类
把消息推送中定义的所有消息都有的字段提取出来,封装成一个基类,这些公有的字段包括:ToUserName(开发者微信号)、FromUserName(发送方帐号,OPEN_ID)、CreateTime(消息的创建时间)、MsgType(消息类型)、MsgId(消息ID),封装后基类
1 package com.javen.course.message.resp; 2 3 /** 4 * 响应消息的基类 5 * 消息基类(公众帐号 -> 普通用户) 6 * @author Javen 7 * @Email zyw205@gmail.com 8 * 9 */ 10 public class BaseMessage { 11 // 接收方帐号(收到的OpenID) 12 private String ToUserName; 13 // 开发者微信号 14 private String FromUserName; 15 // 消息创建时间 (整型) 16 private long CreateTime; 17 // 消息类型(text/music/news) 18 private String MsgType; 19 // 位0x0001被标志时,星标刚收到的消息 20 private int FuncFlag; 21 22 public String getToUserName() { 23 return ToUserName; 24 } 25 26 public void setToUserName(String toUserName) { 27 ToUserName = toUserName; 28 } 29 30 public String getFromUserName() { 31 return FromUserName; 32 } 33 34 public void setFromUserName(String fromUserName) { 35 FromUserName = fromUserName; 36 } 37 38 public long getCreateTime() { 39 return CreateTime; 40 } 41 42 public void setCreateTime(long createTime) { 43 CreateTime = createTime; 44 } 45 46 public String getMsgType() { 47 return MsgType; 48 } 49 50 public void setMsgType(String msgType) { 51 MsgType = msgType; 52 } 53 54 public int getFuncFlag() { 55 return FuncFlag; 56 } 57 58 public void setFuncFlag(int funcFlag) { 59 FuncFlag = funcFlag; 60 } 61 }
消息之文本消息
1 package com.javen.course.message.resp; 2 3 /** 4 * 文本消息 5 * @author Javen 6 * @Email zyw205@gmail.com 7 * 8 */ 9 public class TextMessage extends BaseMessage { 10 // 回复的消息内容 11 private String Content; 12 13 public String getContent() { 14 return Content; 15 } 16 17 public void setContent(String content) { 18 Content = content; 19 } 20 }
消息之地理位置消息
1 package com.javen.course.message.resp; 2 3 /** 4 * 响应消息的基类 5 * 消息基类(公众帐号 -> 普通用户) 6 * @author Javen 7 * @Email zyw205@gmial.com 8 * 9 */ 10 public class BaseMessage { 11 // 接收方帐号(收到的OpenID) 12 private String ToUserName; 13 // 开发者微信号 14 private String FromUserName; 15 // 消息创建时间 (整型) 16 private long CreateTime; 17 // 消息类型(text/music/news) 18 private String MsgType; 19 // 位0x0001被标志时,星标刚收到的消息 20 private int FuncFlag; 21 22 public String getToUserName() { 23 return ToUserName; 24 } 25 26 public void setToUserName(String toUserName) { 27 ToUserName = toUserName; 28 } 29 30 public String getFromUserName() { 31 return FromUserName; 32 } 33 34 public void setFromUserName(String fromUserName) { 35 FromUserName = fromUserName; 36 } 37 38 public long getCreateTime() { 39 return CreateTime; 40 } 41 42 public void setCreateTime(long createTime) { 43 CreateTime = createTime; 44 } 45 46 public String getMsgType() { 47 return MsgType; 48 } 49 50 public void setMsgType(String msgType) { 51 MsgType = msgType; 52 } 53 54 public int getFuncFlag() { 55 return FuncFlag; 56 } 57 58 public void setFuncFlag(int funcFlag) { 59 FuncFlag = funcFlag; 60 } 61 }
消息之图文消息
1 package com.javen.course.message.resp; 2 3 import java.util.List; 4 5 /** 6 * 图文消息 7 * @author Javen 8 * @Email zyw205@gmial.com 9 * 10 */ 11 public class NewsMessage extends BaseMessage { 12 // 图文消息个数,限制为10条以内 13 private int ArticleCount; 14 // 多条图文消息信息,默认第一个item为大图 15 private List<Article> Articles; 16 17 public int getArticleCount() { 18 return ArticleCount; 19 } 20 21 public void setArticleCount(int articleCount) { 22 ArticleCount = articleCount; 23 } 24 25 public List<Article> getArticles() { 26 return Articles; 27 } 28 29 public void setArticles(List<Article> articles) { 30 Articles = articles; 31 } 32 }
图文消息中Article类的实体
1 package com.javen.course.message.resp; 2 3 /** 4 * 图文消息中Article类的定义 5 * @author Javen 6 * @Email zyw205@gmial.com 7 * 8 */ 9 public class Article { 10 // 图文消息名称 11 private String Title; 12 // 图文消息描述 13 private String Description; 14 // 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80,限制图片链接的域名需要与开发者填写的基本资料中的Url一致 15 private String PicUrl; 16 // 点击图文消息跳转链接 17 private String Url; 18 19 public String getTitle() { 20 return Title; 21 } 22 23 public void setTitle(String title) { 24 Title = title; 25 } 26 27 public String getDescription() { 28 return null == Description ? "" : Description; 29 } 30 31 public void setDescription(String description) { 32 Description = description; 33 } 34 35 public String getPicUrl() { 36 return null == PicUrl ? "" : PicUrl; 37 } 38 39 public void setPicUrl(String picUrl) { 40 PicUrl = picUrl; 41 } 42 43 public String getUrl() { 44 return null == Url ? "" : Url; 45 } 46 47 public void setUrl(String url) { 48 Url = url; 49 } 50 51 }
消息之音乐消息
1 package com.javen.course.message.resp; 2 3 /** 4 * 音乐消息 响应消息之音乐消息 5 * @author Javen 6 * @Email zyw205@gmail.com 7 * 8 */ 9 public class MusicMessage extends BaseMessage { 10 // 音乐 11 private Music Music; 12 13 public Music getMusic() { 14 return Music; 15 } 16 17 public void setMusic(Music music) { 18 Music = music; 19 } 20 }
音乐消息中Music类的实体
package com.javen.course.message.resp; /** * 音乐消息中Music类的定义 * @author Javen * @Email zyw205@gmail.com * */ 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; } }
解析请求消息
微信服务器会将用户的请求通过doPost方法发送给我们,回顾接入成为开发者
微信公众帐号开发教程第4篇-----开发模式启用及接口配置Java
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO 消息的接收、处理、响应 }
解析微信发来的请求(XML)
这里我们借助于开源框架dom4j去解析xml(这里使用的是dom4j-1.6.1.jar),然后将解析得到的结果存入HashMap
如何将响应消息转换成xml返回
这里我们将采用开源框架xstream来实现Java类到xml的转换(这里使用的是xstream-1.3.1.jar)
消息处理类型的封装
以上代码如下:
1 package com.javen.course.util; 2 3 import java.io.InputStream; 4 import java.io.Writer; 5 import java.util.HashMap; 6 import java.util.List; 7 import java.util.Map; 8 9 import javax.servlet.http.HttpServletRequest; 10 11 import org.dom4j.Document; 12 import org.dom4j.Element; 13 import org.dom4j.io.SAXReader; 14 15 16 import com.javen.course.message.resp.Article; 17 import com.javen.course.message.resp.MusicMessage; 18 import com.javen.course.message.resp.NewsMessage; 19 import com.javen.course.message.resp.TextMessage; 20 import com.thoughtworks.xstream.XStream; 21 import com.thoughtworks.xstream.core.util.QuickWriter; 22 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 23 import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; 24 import com.thoughtworks.xstream.io.xml.XppDriver; 25 26 /** 27 * 消息工具类 28 * @author Javen 29 * @Email zyw205@gmail.com 30 */ 31 public class MessageUtil { 32 /** 33 * 返回消息类型:文本 34 */ 35 public static final String RESP_MESSAGE_TYPE_TEXT = "text"; 36 37 /** 38 * 返回消息类型:音乐 39 */ 40 public static final String RESP_MESSAGE_TYPE_MUSIC = "music"; 41 42 /** 43 * 返回消息类型:图文 44 */ 45 public static final String RESP_MESSAGE_TYPE_NEWS = "news"; 46 47 /** 48 * 请求消息类型:文本 49 */ 50 public static final String REQ_MESSAGE_TYPE_TEXT = "text"; 51 52 /** 53 * 请求消息类型:图片 54 */ 55 public static final String REQ_MESSAGE_TYPE_IMAGE = "image"; 56 57 /** 58 * 请求消息类型:链接 59 */ 60 public static final String REQ_MESSAGE_TYPE_LINK = "link"; 61 62 /** 63 * 请求消息类型:地理位置 64 */ 65 public static final String REQ_MESSAGE_TYPE_LOCATION = "location"; 66 67 /** 68 * 请求消息类型:音频 69 */ 70 public static final String REQ_MESSAGE_TYPE_VOICE = "voice"; 71 72 /** 73 * 请求消息类型:推送 74 */ 75 public static final String REQ_MESSAGE_TYPE_EVENT = "event"; 76 77 /** 78 * 事件类型:subscribe(订阅) 79 */ 80 public static final String EVENT_TYPE_SUBSCRIBE = "subscribe"; 81 82 /** 83 * 事件类型:unsubscribe(取消订阅) 84 */ 85 public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe"; 86 87 /** 88 * 事件类型:CLICK(自定义菜单点击事件) 89 */ 90 public static final String EVENT_TYPE_CLICK = "CLICK"; 91 92 /** 93 * 事件类型:scan(用户已关注时的事件推送) 94 */ 95 public static final String EVENT_TYPE_SCAN = "SCAN"; 96 97 /** 98 * 解析微信发来的请求(XML) 99 * 100 * @param request 101 * @return 102 * @throws Exception 103 */ 104 @SuppressWarnings("unchecked") 105 public static Map<String, String> parseXml(HttpServletRequest request) throws Exception { 106 // 将解析结果存储在HashMap中 107 Map<String, String> map = new HashMap<String, String>(); 108 109 // 从request中取得输入流 110 InputStream inputStream = request.getInputStream(); 111 // 读取输入流 112 SAXReader reader = new SAXReader(); 113 Document document = reader.read(inputStream); 114 // 得到xml根元素 115 Element root = document.getRootElement(); 116 // 得到根元素的所有子节点 117 List<Element> elementList = root.elements(); 118 119 // 遍历所有子节点 120 for (Element e : elementList) 121 map.put(e.getName(), e.getText()); 122 123 // 释放资源 124 inputStream.close(); 125 inputStream = null; 126 127 return map; 128 } 129 130 /** 131 * 文本消息对象转换成xml 132 * 133 * @param textMessage 文本消息对象 XStream是一个Java对象和XML相互转换的工具 134 * @return xml 135 */ 136 public static String textMessageToXml(TextMessage textMessage) { 137 xstream.alias("xml", textMessage.getClass()); 138 return xstream.toXML(textMessage); 139 } 140 141 /** 142 * 音乐消息对象转换成xml 143 * 144 * @param musicMessage 音乐消息对象 145 * @return xml 146 */ 147 public static String musicMessageToXml(MusicMessage musicMessage) { 148 xstream.alias("xml", musicMessage.getClass()); 149 return xstream.toXML(musicMessage); 150 } 151 152 /** 153 * 图文消息对象转换成xml 154 * 155 * @param newsMessage 图文消息对象 156 * @return xml 157 */ 158 public static String newsMessageToXml(NewsMessage newsMessage) { 159 xstream.alias("xml", newsMessage.getClass()); 160 xstream.alias("item", new Article().getClass()); 161 return xstream.toXML(newsMessage); 162 } 163 164 /** 165 * 扩展xstream,使其支持CDATA块 166 * 167 */ 168 private static XStream xstream = new XStream(new XppDriver() { 169 public HierarchicalStreamWriter createWriter(Writer out) { 170 return new PrettyPrintWriter(out) { 171 // 对所有xml节点的转换都增加CDATA标记 172 boolean cdata = true; 173 174 @SuppressWarnings("unchecked") 175 public void startNode(String name, Class clazz) { 176 super.startNode(name, clazz); 177 } 178 179 protected void writeText(QuickWriter writer, String text) { 180 if (cdata) { 181 writer.write("<![CDATA["); 182 writer.write(text); 183 writer.write("]]>"); 184 } else { 185 writer.write(text); 186 } 187 } 188 }; 189 } 190 }); 191 }
到这里关于消息及消息处理工具的封装基本完成,其实就是对请求消息/响应消息建立了与之对应的Java类、对xml消息进行解析、将响应消息的Java对象转换成xml
我的微信公众账号 人脸识别、音乐点播、在线翻译、天气查询、公交查询、周公解梦、星座运势、手机归属地查询、聊天唠嗑等
欢迎加入群:347245650 345531810 进行讨论相互交流 我的微信号:572839485