微信公众平台开发教程Java版 消息接收和发送

Posted 疯子加天才

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信公众平台开发教程Java版 消息接收和发送相关的知识,希望对你有一定的参考价值。

https://www.iteye.com/blog/tuposky-2017429

前面两章已经介绍了如何接入微信公众平台,这一章说说消息的接收和发送

可以先了解公众平台的消息api接口(接收消息,发送消息)

http://mp.weixin.qq.com/wiki/index.php



 

接收消息

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

 

 http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF

 

接收的消息类型有6种,分别为:

可以根据官方的api提供的字段建立对应的实体类

如:文本消息

 

有很多属性是所有消息类型都需要的,可以把这些信息提取出来建立一个基类

 

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.req;  
  2.   
  3. /** 
  4.  * 消息基类(用户 -> 公众帐号) 
  5.  *  
  6.  */  
  7. public class BaseMessage {  
  8.     /** 
  9.      * 开发者微信号 
  10.      */  
  11.     private String ToUserName;  
  12.     /** 
  13.      * 发送方帐号(一个OpenID) 
  14.      */  
  15.     private String FromUserName;  
  16.     /** 
  17.      * 消息创建时间 (整型) 
  18.      */  
  19.     private long CreateTime;  
  20.   
  21.     /** 
  22.      * 消息类型 text、image、location、link 
  23.      */  
  24.     private String MsgType;  
  25.   
  26.     /** 
  27.      * 消息id,64位整型 
  28.      */  
  29.     private long MsgId;  
  30.   
  31.     public String getToUserName() {  
  32.         return ToUserName;  
  33.     }  
  34.   
  35.     public void setToUserName(String toUserName) {  
  36.         ToUserName = toUserName;  
  37.     }  
  38.   
  39.     public String getFromUserName() {  
  40.         return FromUserName;  
  41.     }  
  42.   
  43.     public void setFromUserName(String fromUserName) {  
  44.         FromUserName = fromUserName;  
  45.     }  
  46.   
  47.     public long getCreateTime() {  
  48.         return CreateTime;  
  49.     }  
  50.   
  51.     public void setCreateTime(long createTime) {  
  52.         CreateTime = createTime;  
  53.     }  
  54.   
  55.     public String getMsgType() {  
  56.         return MsgType;  
  57.     }  
  58.   
  59.     public void setMsgType(String msgType) {  
  60.         MsgType = msgType;  
  61.     }  
  62.   
  63.     public long getMsgId() {  
  64.         return MsgId;  
  65.     }  
  66.   
  67.     public void setMsgId(long msgId) {  
  68.         MsgId = msgId;  
  69.     }  
  70.   
  71. }  

 接收的文本消息

 

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.req;  
  2.   
  3. /** 
  4.  * 文本消息 
  5.  */  
  6. public class TextMessage extends BaseMessage {  
  7.     /** 
  8.      * 回复的消息内容 
  9.      */  
  10.     private String Content;  
  11.   
  12.     public String getContent() {  
  13.         return Content;  
  14.     }  
  15.   
  16.     public void setContent(String content) {  
  17.         Content = content;  
  18.     }  
  19. }  

 接收的图片消息

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.req;  
  2.   
  3. public class ImageMessage extends BaseMessage{  
  4.   
  5.     private String picUrl;  
  6.   
  7.     public String getPicUrl() {  
  8.         return picUrl;  
  9.     }  
  10.   
  11.     public void setPicUrl(String picUrl) {  
  12.         this.picUrl = picUrl;  
  13.     }  
  14.       
  15. }  

 

 

接收的链接消息

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.req;  
  2.   
  3.   
  4. public class LinkMessage extends BaseMessage {  
  5.     /** 
  6.      * 消息标题 
  7.      */  
  8.     private String Title;  
  9.     /** 
  10.      * 消息描述 
  11.      */  
  12.     private String Description;  
  13.     /** 
  14.      * 消息链接 
  15.      */  
  16.     private String Url;  
  17.   
  18.     public String getTitle() {  
  19.         return Title;  
  20.     }  
  21.   
  22.     public void setTitle(String title) {  
  23.         Title = title;  
  24.     }  
  25.   
  26.     public String getDescription() {  
  27.         return Description;  
  28.     }  
  29.   
  30.     public void setDescription(String description) {  
  31.         Description = description;  
  32.     }  
  33.   
  34.     public String getUrl() {  
  35.         return Url;  
  36.     }  
  37.   
  38.     public void setUrl(String url) {  
  39.         Url = url;  
  40.     }  
  41.   
  42. }  

 

 接收的语音消息

 

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.req;  
  2.   
  3. /** 
  4.  * 语音消息 
  5.  *  
  6.  * @author Caspar 
  7.  *  
  8.  */  
  9. public class VoiceMessage extends BaseMessage {  
  10.     /** 
  11.      * 媒体ID 
  12.      */  
  13.     private String MediaId;  
  14.     /** 
  15.      * 语音格式 
  16.      */  
  17.     private String Format;  
  18.   
  19.     public String getMediaId() {  
  20.         return MediaId;  
  21.     }  
  22.   
  23.     public void setMediaId(String mediaId) {  
  24.         MediaId = mediaId;  
  25.     }  
  26.   
  27.     public String getFormat() {  
  28.         return Format;  
  29.     }  
  30.   
  31.     public void setFormat(String format) {  
  32.         Format = format;  
  33.     }  
  34.   
  35. }  

 接收的地理位置消息

 

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.req;  
  2.   
  3.   
  4. /** 
  5.  * 位置消息 
  6.  *  
  7.  * @author caspar 
  8.  *  
  9.  */  
  10. public class LocationMessage extends BaseMessage {  
  11.     /** 
  12.      * 地理位置维度 
  13.      */  
  14.     private String Location_X;  
  15.     /** 
  16.      * 地理位置经度 
  17.      */  
  18.     private String Location_Y;  
  19.   
  20.     /** 
  21.      * 地图缩放大小 
  22.      */  
  23.     private String Scale;  
  24.   
  25.     /** 
  26.      * 地理位置信息 
  27.      */  
  28.     private String Label;  
  29.   
  30.     public String getLocation_X() {  
  31.         return Location_X;  
  32.     }  
  33.   
  34.     public void setLocation_X(String location_X) {  
  35.         Location_X = location_X;  
  36.     }  
  37.   
  38.     public String getLocation_Y() {  
  39.         return Location_Y;  
  40.     }  
  41.   
  42.     public void setLocation_Y(String location_Y) {  
  43.         Location_Y = location_Y;  
  44.     }  
  45.   
  46.     public String getScale() {  
  47.         return Scale;  
  48.     }  
  49.   
  50.     public void setScale(String scale) {  
  51.         Scale = scale;  
  52.     }  
  53.   
  54.     public String getLabel() {  
  55.         return Label;  
  56.     }  
  57.   
  58.     public void setLabel(String label) {  
  59.         Label = label;  
  60.     }  
  61.   
  62. }  

 

 

发送被动响应消息

    对于每一个POST请求,开发者在响应包(Get)中返回特定XML结构,对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。请注意,回复图片等多媒体消息时需要预先上传多媒体文件到微信服务器,只支持认证服务号。

 

    同样,建立响应消息的对应实体类

    也把公共的属性提取出来,封装成基类

 

     响应消息的基类

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.resp;  
  2.   
  3. /** 
  4.  * 消息基类(公众帐号 -> 用户) 
  5.  */  
  6. public class BaseMessage {  
  7.       
  8.     /** 
  9.      * 接收方帐号(收到的OpenID) 
  10.      */  
  11.     private String ToUserName;  
  12.     /** 
  13.      * 开发者微信号 
  14.      */  
  15.     private String FromUserName;  
  16.     /** 
  17.      * 消息创建时间 (整型) 
  18.      */  
  19.     private long CreateTime;  
  20.       
  21.     /** 
  22.      * 消息类型 
  23.      */  
  24.     private String MsgType;  
  25.       
  26.     /** 
  27.      * 位0x0001被标志时,星标刚收到的消息 
  28.      */  
  29.     private int FuncFlag;  
  30.   
  31.     public String getToUserName() {  
  32.         return ToUserName;  
  33.     }  
  34.   
  35.     public void setToUserName(String toUserName) {  
  36.         ToUserName = toUserName;  
  37.     }  
  38.   
  39.     public String getFromUserName() {  
  40.         return FromUserName;  
  41.     }  
  42.   
  43.     public void setFromUserName(String fromUserName) {  
  44.         FromUserName = fromUserName;  
  45.     }  
  46.   
  47.     public long getCreateTime() {  
  48.         return CreateTime;  
  49.     }  
  50.   
  51.     public void setCreateTime(long createTime) {  
  52.         CreateTime = createTime;  
  53.     }  
  54.   
  55.     public String getMsgType() {  
  56.         return MsgType;  
  57.     }  
  58.   
  59.     public void setMsgType(String msgType) {  
  60.         MsgType = msgType;  
  61.     }  
  62.   
  63.     public int getFuncFlag() {  
  64.         return FuncFlag;  
  65.     }  
  66.   
  67.     public void setFuncFlag(int funcFlag) {  
  68.         FuncFlag = funcFlag;  
  69.     }  
  70. }  

 

 

    响应文本消息

   

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.resp;  
  2.   
  3.   
  4. /** 
  5.  * 文本消息 
  6.  */  
  7. public class TextMessage extends BaseMessage {  
  8.     /** 
  9.      * 回复的消息内容 
  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. }  

 

 

响应图文消息

   

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.resp;  
  2.   
  3. import java.util.List;  
  4.   
  5. /** 
  6.  * 多图文消息, 
  7.  * 单图文的时候 Articles 只放一个就行了 
  8.  * @author Caspar.chen 
  9.  */  
  10. public class NewsMessage extends BaseMessage {  
  11.     /** 
  12.      * 图文消息个数,限制为10条以内 
  13.      */  
  14.     private int ArticleCount;  
  15.     /** 
  16.      * 多条图文消息信息,默认第一个item为大图 
  17.      */  
  18.     private List<Article> Articles;  
  19.   
  20.     public int getArticleCount() {  
  21.         return ArticleCount;  
  22.     }  
  23.   
  24.     public void setArticleCount(int articleCount) {  
  25.         ArticleCount = articleCount;  
  26.     }  
  27.   
  28.     public List<Article> getArticles() {  
  29.         return Articles;  
  30.     }  
  31.   
  32.     public void setArticles(List<Article> articles) {  
  33.         Articles = articles;  
  34.     }  
  35. }  

 图文消息的定义

 

 

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.resp;  
  2.   
  3. /** 
  4.  * 图文消息 
  5.  *  
  6.  */  
  7. public class Article {  
  8.     /** 
  9.      * 图文消息名称 
  10.      */  
  11.     private String Title;  
  12.   
  13.     /** 
  14.      * 图文消息描述 
  15.      */  
  16.     private String Description;  
  17.   
  18.     /** 
  19.      * 图片链接,支持JPG、PNG格式,<br> 
  20.      * 较好的效果为大图640*320,小图80*80 
  21.      */  
  22.     private String PicUrl;  
  23.   
  24.     /** 
  25.      * 点击图文消息跳转链接 
  26.      */  
  27.     private String Url;  
  28.   
  29.     public String getTitle() {  
  30.         return Title;  
  31.     }  
  32.   
  33.     public void setTitle(String title) {  
  34.         Title = title;  
  35.     }  
  36.   
  37.     public String getDescription() {  
  38.         return null == Description ? "" : Description;  
  39.     }  
  40.   
  41.     public void setDescription(String description) {  
  42.         Description = description;  
  43.     }  
  44.   
  45.     public String getPicUrl() {  
  46.         return null == PicUrl ? "" : PicUrl;  
  47.     }  
  48.   
  49.     public void setPicUrl(String picUrl) {  
  50.         PicUrl = picUrl;  
  51.     }  
  52.   
  53.     public String getUrl() {  
  54.         return null == Url ? "" : Url;  
  55.     }  
  56.   
  57.     public void setUrl(String url) {  
  58.         Url = url;  
  59.     }  
  60.   
  61. }  

 

 

响应音乐消息

 

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.resp;  
  2.   
  3.   
  4.   
  5. /** 
  6.  * 音乐消息 
  7.  */  
  8. public class MusicMessage extends BaseMessage {  
  9.     /** 
  10.      * 音乐 
  11.      */  
  12.     private Music Music;  
  13.   
  14.     public Music getMusic() {  
  15.         return Music;  
  16.     }  
  17.   
  18.     public void setMusic(Music music) {  
  19.         Music = music;  
  20.     }  
  21. }  

 

 

音乐消息的定义

Java代码  收藏代码
  1. package com.ifp.weixin.entity.Message.resp;  
  2.   
  3. /** 
  4.  * 音乐消息 
  5.  */  
  6. public class Music {  
  7.     /** 
  8.      * 音乐名称 
  9.      */  
  10.     private String Title;  
  11.       
  12.     /** 
  13.      * 音乐描述 
  14.      */  
  15.     private String Description;  
  16.       
  17.     /** 
  18.      * 音乐链接 
  19.      */  
  20.     private String MusicUrl;  
  21.       
  22.     /** 
  23.      * 高质量音乐链接,WIFI环境优先使用该链接播放音乐 
  24.      */  
  25.     private String HQMusicUrl;  
  26.   
  27.     public String getTitle() {  
  28.         return Title;  
  29.     }  
  30.   
  31.     public void setTitle(String title) {  
  32.         Title = title;  
  33.     }  
  34.   
  35.     public String getDescription() {  
  36.         return Description;  
  37.     }  
  38.   
  39.     public void setDescription(String description) {  
  40.         Description = description;  
  41.     }  
  42.   
  43.     public String getMusicUrl() {  
  44.         return MusicUrl;  
  45.     }  
  46.   
  47.     public void setMusicUrl(String musicUrl) {  
  48.         MusicUrl = musicUrl;  
  49.     }  
  50.   
  51.     public String getHQMusicUrl() {  
  52.         return HQMusicUrl;  
  53.     }  
  54.   
  55.     public void setHQMusicUrl(String musicUrl) {  
  56.         HQMusicUrl = musicUrl;  
  57.     }  
  58.   
  59. }  

 
 构建好之后的项目结构图为

 

 

到这里,请求消息和响应消息的实体类都定义好了

 

解析请求消息

 

用户向微信公众平台发送消息后,微信公众平台会通过post请求发送给我们。

上一章中WeixinController 类的post方法我们空着

 

 现在我们要在这里处理用户请求了。

 

因为微信的发送和接收都是用xml格式的,所以我们需要处理请求过来的xml格式。

发送的时候也需要转化成xml格式再发送给微信,所以封装了消息处理的工具类,用到dome4j和xstream两个jar包

Java代码  收藏代码
  1. package com.ifp.weixin.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. import com.ifp.weixin.entity.Message.resp.Article;  
  16. import com.ifp.weixin.entity.Message.resp.MusicMessage;  
  17. import com.ifp.weixin.entity.Message.resp.NewsMessage;  
  18. import com.ifp.weixin.entity.Message.resp.TextMessage;  
  19. import com.thoughtworks.xstream.XStream;  
  20. import com.thoughtworks.xstream.core.util.QuickWriter;  
  21. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;  
  22. import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;  
  23. import com.thoughtworks.xstream.io.xml.XppDriver;  
  24.   
  25. /** 
  26.  * 消息工具类 
  27.  *  
  28.  */  
  29. public class MessageUtil {  
  30.   
  31.     /** 
  32.      * 解析微信发来的请求(XML) 
  33.      *  
  34.      * @param request 
  35.      * @return 
  36.      * @throws Exception 
  37.      */  
  38.     public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {  
  39.         // 将解析结果存储在HashMap中  
  40.         Map<String, String> map = new HashMap<String, String>();  
  41.   
  42.         // 从request中取得输入流  
  43.         InputStream inputStream = request.getInputStream();  
  44.         // 读取输入流  
  45.         SAXReader reader = new SAXReader();  
  46.         Document document = reader.read(inputStream);  
  47.         // 得到xml根元素  
  48.         Element root = document.getRootElement();  
  49.         // 得到根元素的所有子节点  
  50.           
  51.         @SuppressWarnings("unchecked")  
  52.         List<Element> elementList = root.elements();  
  53.   
  54.         // 遍历所有子节点  
  55.         for (Element e : elementList)  
  56.             map.put(e.getName(), e.getText());  
  57.   
  58.         // 释放资源  
  59.         inputStream.close();  
  60.         inputStream = null;  
  61.   
  62.         return map;  
  63.     }  
  64.   
  65.     /** 
  66.      * 文本消息对象转换成xml 
  67.      *  
  68.      * @param textMessage 文本消息对象 
  69.      * @return xml 
  70.      */  
  71.     public static String textMessageToXml(TextMessage textMessage) {  
  72.         xstream.alias("xml", textMessage.getClass());  
  73.         return xstream.toXML(textMessage);  
  74.     }  
  75.   
  76.     /** 
  77.      * 音乐消息对象转换成xml 
  78.      *  
  79.      * @param musicMessage 音乐消息对象 
  80.      * @return xml 
  81.      */  
  82.     public static String musicMessageToXml(MusicMessage musicMessage) {  
  83.         xstream.alias("xml", musicMessage.getClass());  
  84.         return xstream.toXML(musicMessage);  
  85.     }  
  86.   
  87.     /** 
  88.      * 图文消息对象转换成xml 
  89.      *  
  90.      * @param newsMessage 图文消息对象 
  91.      * @return xml 
  92.      */  
  93.     public static String newsMessageToXml(NewsMessage newsMessage) {  
  94.         xstream.alias("xml", newsMessage.getClass());  
  95.         xstream.alias("item", new Article().getClass());  
  96.         return xstream.toXML(newsMessage);  
  97.     }  
  98.   
  99.     /** 
  100.      * 扩展xstream,使其支持CDATA块 
  101.      *  
  102.      */  
  103.     private static XStream xstream = new XStream(new XppDriver() {  
  104.         public HierarchicalStreamWriter createWriter(Writer out) {  
  105.             return new PrettyPrintWriter(out) {  
  106.                 // 对所有xml节点的转换都增加CDATA标记  
  107.                 boolean cdata = true;  
  108.                 protected void writeText(QuickWriter writer, String text) {  
  109.                     if (cdata) {  
  110.                         writer.write("<![CDATA[");  
  111.                         writer.write(text);  
  112.                         writer.write("]]>");  
  113.                     } else {  
  114.                         writer.write(text);  
  115.                     }  
  116.                 }  
  117.             };  
  118.         }  
  119.     });  
  120.       
  121.       
  122. }  

 接下来在处理业务逻辑,建立一个接收并响应消息的service类,并针对用户输入的1或2回复不同的信息给用户

 

Java代码  收藏代码
  1. package com.ifp.weixin.biz.core.impl;  
  2.   
  3. import java.util.Date;  
  4. import java.util.Map;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7.   
  8. import org.apache.log4j.Logger;  
  9. import org.springframework.stereotype.Service;  
  10.   
  11. import com.ifp.weixin.biz.core.CoreService;  
  12. import com.ifp.weixin.constant.Constant;  
  13. import com.ifp.weixin.entity.Message.resp.TextMessage;  
  14. import com.ifp.weixin.util.MessageUtil;  
  15.   
  16. @Service("coreService")  
  17. public class CoreServiceImpl implements CoreService{  
  18.   
  19.     public static Logger log = Logger.getLogger(CoreServiceImpl.class);  
  20.       
  21.       
  22.     @Override  以上是关于微信公众平台开发教程Java版 消息接收和发送的主要内容,如果未能解决你的问题,请参考以下文章

    微信公众平台开发入门:[8]聊天机器人可开发

    微信公众号开发入门教程第一篇

    Java微信公众平台开发_03_消息管理之被动回复消息

    柳峰微信公众平台开发教程企业号修改篇(AES验证)

    java微信公众平台开发

    微信公众平台怎么开发?