java微信开发API解析(二)-获取消息和回复消息

说明

* 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/2016 5:34:36 PM )进行开发演示。

* 编辑平台:myeclipse10.7+win32+jdk1.7+tomcat7.0 * server:阿里云 windows server 2008 64bits * 平台要求:servlet使用注解方式。平台要求:j2ee6.0+、jdk6.0+、tomcat7.0+ * 演示更加注重于api解析。 * 为了便于測试说明。每一个測试用例为独立,不依赖于其他方法。

对于封装,不多加考虑。

* 演示尽可能依照API要求进行,目的:了解文档使用方式,达到举一反三的效果。 * 知识要求:坚固的java基础、了解http网络通信知识、对于javaweb有足够了解、json解析 * 在每篇文章结束会给出该部分演示源代码。

在分析完API之后,会以源代码包的形式给出全部演示源代码。 * 当前时间:4/3/2016 5:32:57 PM ,以该时间为准。

文档原文-消息管理(摘要)

  • 文档地址:http://mp.weixin.qq.com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
  • 消息管理
    • 接收消息-接收普通消息
    • 接收消息-接收事件推送
    • 发送消息-被动回复消息
    • 发送消息-被动回复时的加解密
    • 发送消息-客服消息
    • 发送消息-群发接口
    • 发送消息-模板消息接口
    • 发送消息-模板消息运营规范
    • 获取公众号自己主动回复配置

文档理解

  • 接收消息

    • 文档这样解释:​当普通微信用户向公众账号发消息时。微信server将POST消息的XML数据包到开发人员填写的URL上。
    • 理解:微信server将用户发送的消息通过Post流的形式返回给req。

      当我们想要获取用户发送的消息时,能够通过req.getInputStream()获取。

      当然。我们能够依据文档上关于消息的返回的xml格式,进行必要的解析。

    • 实现:

      /** 该部分我们获取用户发送的信息。而且解析成<K,V>的形式进行显示*/
      // 解析用户发送过来的信息
      InputStream is = req.getInputStream();// 拿取请求流
      // 将解析结果存储在HashMap中
      Map<String, String> map = new HashMap<String, String>();
      // 解析xml。将获取到的返回结果xml进行解析成我们习惯的文字信息
      SAXReader reader = new SAXReader();// 第三方jar:dom4j【百度:saxreader解析xml】
      Document document = null;
      try {document = reader.read(is);
      } catch (DocumentException e1) {// TODO Auto-generated catch blocke1.printStackTrace();
      }
      // 得到xml根元素
      Element root = document.getRootElement();
      // 得到根元素的全部子节点
      List<Element> elementList = root.elements();// 遍历全部子节点
      for (Element e : elementList)map.put(e.getName(), e.getText());// 測试输出
      Set<String> keySet = map.keySet();
      // 測试输出解析后用户发过来的信息
      System.out.println(TAG + ":解析用户发送过来的信息開始");
      for (String key : keySet) {System.out.println(key + ":" + map.get(key));
      }
      System.out.println(TAG + ":解析用户发送过来的信息结束");
      
  • 发送消息

    • 文档这样解释:​当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时)。会产生一个POST请求,开发人员能够在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息事实上并非一种接口,而是对微信server发过来消息的一次回复。
    • 理解:用户发送请求,会产生一个POST请求。我们能够通过Respone进行回复消息。可是,回复的内容有严格的格式要求。仅仅有满足格式要求,微信server才会进行处理返回给用户。

      通过查看文档“消息管理”模块,我们能够看到微信中有各种各样的消息。每类消息都有自己特定的格式要求。我们必须依照要求才干够正常的给用户返回特定的信息。

      我们尝试依照文档的要求格式给用户回复文本信息、图文消息。

      重点:依照文档要求构造须要的參数。

      特别注意:參数区分大写和小写。

    • 实现1-回复普通文本消息:

      //实例1:发送普通文本消息,请查看文档关于“回复文本消息”的xml格式// 第一步:依照回复文本信息构造须要的參数
      TextMsg textMsg = new TextMsg();
      textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
      textMsg.setFromUserName(map.get("ToUserName"));
      textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
      textMsg.setMsgType("text");// 文本类型消息
      textMsg.setContent("我是server回复给用户的信息");// // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
      XStream xStream = new XStream();
      xStream.alias("xml", textMsg.getClass());
      String textMsg2Xml = xStream.toXML(textMsg);
      System.out.println(textMsg2Xml);// // 第三步。发送xml的格式信息给微信server,server转发给用户
      PrintWriter printWriter = resp.getWriter();
      printWriter.print(textMsg2Xml);
      
    • 实现2-回复图文消息:

      //实例2,发送图文消息。

      请查看文档关于“回复图文消息”的xml格式 // 第一步:依照回复图文信息构造须要的參数 List<Article> articles = new ArrayList<Article>(); Article a = new Article(); a.setTitle("我是图片标题"); a.setUrl("www.baidu.com");// 该地址是点击图片跳转后 a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// 该地址是一个有效的图片地址 a.setDescription("我是图片的描写叙述"); articles.add(a); PicAndTextMsg picAndTextMsg = new PicAndTextMsg(); picAndTextMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反 picAndTextMsg.setFromUserName(map.get("ToUserName")); picAndTextMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型) picAndTextMsg.setMsgType("news");// 图文类型消息 picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles); // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】 XStream xStream = new XStream(); xStream.alias("xml", picAndTextMsg.getClass()); xStream.alias("item", a.getClass()); String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg); System.out.println(picAndTextMsg2Xml); // 第三步,发送xml的格式信息给微信server,server转发给用户 PrintWriter printWriter = resp.getWriter(); printWriter.print(picAndTextMsg2Xml);

该部分全部操作源代码,能够直接使用

  • CoreServlet.java(包括server接入、接收用户发送消息、回复普通文字消息、回复图文消息。

    须要第三方jar:dom4j、xstream)

    package com.gist.servlet;import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;import com.gist.bean.Article;
    import com.gist.bean.PicAndTextMsg;
    import com.thoughtworks.xstream.XStream;/*** @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://blog.csdn.net/wgyscsf</n>*         编写时期 2016-4-3 下午4:34:05*/
    @WebServlet("/CoreServlet")
    public class CoreServlet extends HttpServlet {private static final long serialVersionUID = 1L;String TAG = "CoreServlet";/** 第二步:验证server地址的有效性 开发人员提交信息后,微信server将发送GET请求到填写的server地址URL上,* GET请求携带四个參数:signature、timestamp、nonce、echostr* 开发人员通过检验signature对请求进行校验(以下有校验方式)。 若确认此次GET请求来自微信server。请原样返回echostr參数内容,* 则接入生效, 成为开发人员成功。否则接入失败。* * 加密/校验流程例如以下: 1. 将token、timestamp、nonce三个參数进行字典序排序 2.* 将三个參数字符串拼接成一个字符串进行sha1加密 3. 开发人员获得加密后的字符串可与signature对照。标识该请求来源于微信*//** 字典排序(lexicographical* order)是一种对于随机变量形成序列的排序方法。其方法是,依照字母顺序,或者数字小大顺序,由小到大的形成序列。*/@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 设置编码req.setCharacterEncoding("utf-8");resp.setContentType("html/text;charset=utf-8");resp.setCharacterEncoding("utf-8");// 获取输出流PrintWriter printWriter = resp.getWriter();// 设置一个全局的token,开发人员自己设置。api这样解释:Token可由开发人员能够随意填写,// 用作生成签名(该Token会和接口URL中包括的Token进行比对,从而验证安全性)String token = "wgyscsf";// 依据api说明,获取上述四个參数String signature = req.getParameter("signature");String timestamp = req.getParameter("timestamp");String nonce = req.getParameter("nonce");String echostr = req.getParameter("echostr");// // temp:暂时打印,观看返回參数情况// System.out.println(TAG + ":signature:" + signature + ",timestamp:"// + timestamp + ",nonce:" + nonce + ",echostr:" + echostr);// 依据api所说的“加密/校验流程”进行接入。共计三步// 第一步:将token、timestamp、nonce三个參数进行字典序排序String[] parms = new String[] { token, timestamp, nonce };// 将须要字典序排列的字符串放到数组中Arrays.sort(parms);// 依照api要求进行字典序排序// 第二步:将三个參数字符串拼接成一个字符串进行sha1加密// 拼接字符串String parmsString = "";// 注意。此处不能=null。for (int i = 0; i < parms.length; i++) {parmsString += parms[i];}// sha1加密String mParms = null;// 加密后的结果MessageDigest digest = null;try {digest = java.security.MessageDigest.getInstance("SHA");} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();}digest.update(parmsString.getBytes());byte messageDigest[] = digest.digest();// Create Hex StringStringBuffer hexString = new StringBuffer();// 字节数组转换为 十六进制 数for (int i = 0; i < messageDigest.length; i++) {String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {hexString.append(0);}hexString.append(shaHex);}mParms = hexString.toString();// 加密结果/** api要求: 若确认此次GET请求来自微信server。请原样返回echostr參数内容。 则接入生效。 成为开发人员成功,否则接入失败。

    */ // 第三步: 开发人员获得加密后的字符串可与signature对照。标识该请求来源于微信接入成功。 // System.out.println(TAG + ":" + mParms + "---->" + signature); if (mParms.equals(signature)) { // System.out.println(TAG + ":" + mParms + "---->" + signature); printWriter.write(echostr); } else { // 接入失败,不用回写 // System.out.println(TAG + "接入失败"); } } /* * 查看api文档关于收发消息推送的消息格式基本一致。 如以下格式: <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> * <Content><![CDATA[this is a test]]></Content> * <MsgId>1234567890123456</MsgId> </xml> 那么,我们就能够进行统一处理。 */ /* * 我们先获取输入流,看输入流里面的信息。通过測试打印输出流。我们能够看到每次用户请求,都会收到req请求。请求格式是xml格式。该信息在文档中有说明。 */ /* * 特别注意。req.getInputStream()仅仅能获取一次,而且仅仅能读取一次。假设想要多次读取,须要另外想办法。为了简单起见, * 我们仅仅获取一次req.getInputStream(),不再打印输出流信息。直接打印解析后的信息。 */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置编码 req.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); resp.setCharacterEncoding("utf-8"); /* * 该部分我们获取用户发送的信息,而且解析成<K,V>的形式进行显示 */ // 解析用户发送过来的信息 InputStream is = req.getInputStream();// 拿取请求流 // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息 SAXReader reader = new SAXReader();// 第三方jar:dom4j【百度:saxreader解析xml】 Document document = null; try { document = reader.read(is); } catch (DocumentException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的全部子节点 List<Element> elementList = root.elements(); // 遍历全部子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 測试输出 Set<String> keySet = map.keySet(); // 測试输出解析后用户发过来的信息 System.out.println(TAG + ":解析用户发送过来的信息開始"); for (String key : keySet) { System.out.println(key + ":" + map.get(key)); } System.out.println(TAG + ":解析用户发送过来的信息结束"); /* * 该部分我们尝试依照文档的要求格式给用户回复文本信息、图文消息。重点:依照文档要求构造须要的參数。特别注意:參数区分大写和小写。 */ // //实例1:发送普通文本消息,请查看文档关于“回复文本消息”的xml格式 // // // 第一步:依照回复文本信息构造须要的參数 // TextMsg textMsg = new TextMsg(); // textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反 // textMsg.setFromUserName(map.get("ToUserName")); // textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型) // textMsg.setMsgType("text");// 文本类型消息 // textMsg.setContent("我是server回复给用户的信息"); // // // // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】 // XStream xStream = new XStream(); // xStream.alias("xml", textMsg.getClass()); // String textMsg2Xml = xStream.toXML(textMsg); // System.out.println(textMsg2Xml); // // // // 第三步,发送xml的格式信息给微信server,server转发给用户 // PrintWriter printWriter = resp.getWriter(); // printWriter.print(textMsg2Xml); // //实例2,发送图文消息。请查看文档关于“回复图文消息”的xml格式 // 第一步:依照回复图文信息构造须要的參数 List<Article> articles = new ArrayList<Article>(); Article a = new Article(); a.setTitle("我是图片标题"); a.setUrl("www.baidu.com");// 该地址是点击图片跳转后 a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// 该地址是一个有效的图片地址 a.setDescription("我是图片的描写叙述"); articles.add(a); PicAndTextMsg picAndTextMsg = new PicAndTextMsg(); picAndTextMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反 picAndTextMsg.setFromUserName(map.get("ToUserName")); picAndTextMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型) picAndTextMsg.setMsgType("news");// 图文类型消息 picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles); // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】 XStream xStream = new XStream(); xStream.alias("xml", picAndTextMsg.getClass()); xStream.alias("item", a.getClass()); String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg); System.out.println(picAndTextMsg2Xml); // 第三步,发送xml的格式信息给微信server。server转发给用户 PrintWriter printWriter = resp.getWriter(); printWriter.print(picAndTextMsg2Xml); } }

  • TestMsg.java(普通文字消息bean)

    package com.gist.bean;/*** @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://blog.csdn.net/wgyscsf</n>*         编写时期 2016-4-4 下午2:09:27*/
    public class TextMsg {private String ToUserName;private String FromUserName;private long CreateTime;private String MsgType;@Overridepublic String toString() {return "TextMsg [ToUserName=" + ToUserName + ", FromUserName="+ FromUserName + ", CreateTime=" + CreateTime + ", MsgType="+ MsgType + ", Content=" + Content + "]";}private String Content;public TextMsg(String toUserName, String fromUserName, long createTime,String msgType, String content) {super();ToUserName = toUserName;FromUserName = fromUserName;CreateTime = createTime;MsgType = msgType;Content = content;}public TextMsg() {super();}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 String getContent() {return Content;}public void setContent(String content) {Content = content;}
    }
    
  • Article.java(图文消息内部Article bean)

    package com.gist.bean;/*** @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://blog.csdn.net/wgyscsf</n>*         编写时期 2016-4-4 下午2:47:08*/
    public class Article {private String Title;@Overridepublic String toString() {return "item [Title=" + Title + ", Description=" + Description+ ", PicUrl=" + PicUrl + ", Url=" + 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 getPicUrl() {return PicUrl;}public void setPicUrl(String picUrl) {PicUrl = picUrl;}public String getUrl() {return Url;}public void setUrl(String url) {Url = url;}private String Description;private String PicUrl;private String Url;}
    
  • PicAndTextMsg.java(图文消息 bean)

    package com.gist.bean;import java.util.List;/*** @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://blog.csdn.net/wgyscsf</n>*         编写时期 2016-4-4 下午2:47:08*/
    public class PicAndTextMsg {private String ToUserName;private String FromUserName;private long CreateTime;private String MsgType;private int ArticleCount;private List<Article> Articles;@Overridepublic String toString() {return "PicAndTextMsg [ToUserName=" + ToUserName + ", FromUserName="+ FromUserName + ", CreateTime=" + CreateTime + ", MsgType="+ MsgType + ", ArticleCount=" + ArticleCount + ", Articles="+ Articles + "]";}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 getArticleCount() {return ArticleCount;}public void setArticleCount(int articleCount) {ArticleCount = articleCount;}public List<Article> getArticles() {return Articles;}public void setArticles(List<Article> articles) {Articles = articles;}}
    

转载于:https://www.cnblogs.com/zsychanpin/p/7290789.html

java微信开发API解析(二)-获取消息和回复消息相关推荐

  1. java微信开发API解析(四)-自定义菜单以及个性化菜单实现

    全局说明 * 详细说明请参考前两篇文章. 本文说明 *本文分为五部分:* 工具类AccessTokenUtils的封装* 自定义菜单和个性化菜单文档的阅读解析* 菜单JSON的分析以及构建对应bean ...

  2. 微信公众号Java开发记录(二)接收、回复消息

    文章目录 一.接受消息 将xml数据包解析成Map BaseMessage TextMessage 二.回复消息 将Map转化成xml数据包 一.接受消息 用户向公众号发送的消息是通过我们的那个路径的 ...

  3. java获取微信的通讯录,java微信开发API第三步 微信获取以及保存接口调用凭证

    微信如何获取以及保存接口调用凭证,下面就为大家进行介绍 一.说明 *详细说明请参考前两篇文章. *本文分为三部分: 接口调用凭证access_token的作用以及解释 如何获取接口调用凭证access ...

  4. JAVA微信开发:[17]如何获取所有关注用户

    该方法获取所有关注公共账号的微信用户的openId集合, 再通过openId集合既可以获取所有的用户的信息.   /** * 获取所有的关注用户 * * @return */ public  List ...

  5. java微信开发-消息接收和自动回复

    0.前提条件 1.需要一个公众平台帐号(测试帐号也可以) 2.平台需要被人关注 1.导入jar commons-beanutils-1.8.0.jar commons-collections-3.1. ...

  6. 微信个性化菜单 java_java微信开发API第四步 微信自定义个性化菜单实现

    微信如何实现自定义个性化菜单,下面为大家介绍 一.全局说明 详细说明请参考前两篇文章. 二.本文说明 本文分为五部分: * 工具类AccessTokenUtils的封装 * 自定义菜单和个性化菜单文档 ...

  7. KODI(原XBMC)二次开发完全解析(三)-------获取视频输入流

    上篇讲到player的建立流程KODI(原XBMC)二次开发完全解析(二)-------创建player,接着上篇确定哪一个才是真正干活的player. m_pPlayer->CreatePla ...

  8. Java微信开发_00_资源汇总贴

    1.微信公众平台技术文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432) 2.微信企业号开发接口文档(ht ...

  9. 个人微信开发API协议

    安卓微信的api,个人微信开发API协议,微信 ipad sdk,微信ipad协议,微信web版接口api,微信网页版接口,微信电脑版sdk,微信开发sdk,微信开发API,微信协议,微信接口文档sd ...

最新文章

  1. python在审计中的应用-【干货】Python自动化审计及实现
  2. 如何解决弹出窗口固定大小及内容的问题
  3. 华为p4用鸿蒙系统吗_华为mate40是鸿蒙系统吗
  4. 730阵列卡支持多大硬盘_凯捷月销破2万,配6座头等舱空间,到底有多舒服?试驾了才知道...
  5. 判断一个程序员水平高低的标准?
  6. java 快速框架下载_Aria:简单易用、高效的下载框架(Java)
  7. Python学习-第3课(函数作用域、列表集合字典元祖)
  8. CentOS 6.0 下 VNC 配置方法
  9. hist 和imhist的区别
  10. ArcGIS教程:MapGIS向ArcGIS数据格式转换方法
  11. 机器人动力学-牛顿-欧拉方程
  12. 2021年华中杯A题(马赛克瓷砖选色问题)详细分析
  13. 如何利用PS做文字拼接海报
  14. 相机光学(十一)——镜头
  15. 组件、Prop属性的基本用法
  16. 开发后台界面用 div好,还是frame 框架 好?
  17. Error: Corrupted zip: missing XXX bytes.
  18. 在IDC机房,1m宽带下载速度是多少?
  19. 小王带你了解如何配置静态ip
  20. JavaSE面向对象

热门文章

  1. Typora如何设置图片的默认保存路径
  2. CTFshow web15
  3. 充电枪cp信号控制板_新能源汽车充电头气密性检测是怎么做的呢?
  4. 吴恩达团队最新成果:用深度学习预测死亡概率,改善临终关怀
  5. 由浅入深学习Apache httpd原理与配置
  6. scala语言+Spark学习一箩筐
  7. 在Oracle/SQL Service中通过Function返回Table
  8. CSS选择器(中)——高级选择器
  9. 一般别人去湖大找门,我都笑得半死
  10. 苹果一体机系统恢复_趁双十一大促销,赶紧升级苹果一体机升级SSD固态和液态内存吧...