国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java微信開發第二步 獲取消息和回復消息

2019-11-26 14:19:40
字體:
來源:轉載
供稿:網友

接著上一篇java微信開發API第一步 服務器接入進行學習,下面介紹java微信開發第二步:獲取消息和回復消息,具體內容如下

* 本示例根據微信開發文檔:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/2016 5:34:36 PM )進行開發演示。
* 編輯平臺:myeclipse10.7+win32+jdk1.7+tomcat7.0 
* 服務器:阿里云 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
消息管理
接收消息-接收普通消息
接收消息-接收事件推送
發送消息-被動回復消息
發送消息-被動回復時的加解密
發送消息-客服消息
發送消息-群發接口
發送消息-模板消息接口
發送消息-模板消息運營規范
獲取公眾號自動回復配置

二、文檔理解

1、接收消息

文檔這樣解釋:​當普通微信用戶向公眾賬號發消息時,微信服務器將POST消息的XML數據包到開發者填寫的URL上。
理解:微信服務器將用戶發送的消息通過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 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 + ":解析用戶發送過來的信息結束");  

2、發送消息

文檔這樣解釋:​當用戶發送消息給公眾號時(或某些特定的用戶操作引發的事件推送時),會產生一個POST請求,開發者可以在響應包(Get)中返回特定XML結構,來對該消息進行響應(現支持回復文本、圖片、圖文、語音、視頻、音樂)。嚴格來說,發送被動響應消息其實并不是一種接口,而是對微信服務器發過來消息的一次回復。
理解:用戶發送請求,會產生一個POST請求,我們可以通過Respone進行回復消息。但是,回復的內容有嚴格的格式要求,只有滿足格式要求,微信服務器才會進行處理返回給用戶。通過查看文檔“消息管理”模塊,我們可以看到微信中有各種各樣的消息,每類消息都有自己特定的格式要求,我們必須按照要求才可以正常的給用戶返回特定的信息。我們嘗試按照文檔的要求格式給用戶回復文本信息、圖文消息。重點:按照文檔要求構造需要的參數。特別注意:參數區分大小寫。
1)、實現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("我是服務器回復給用戶的信息");// // 第二步,將構造的信息轉化為微信識別的xml格式【百度:xstream bean轉xml】XStream xStream = new XStream();xStream.alias("xml", textMsg.getClass());String textMsg2Xml = xStream.toXML(textMsg);System.out.println(textMsg2Xml);// // 第三步,發送xml的格式信息給微信服務器,服務器轉發給用戶PrintWriter printWriter = resp.getWriter();printWriter.print(textMsg2Xml);

2)、實現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的格式信息給微信服務器,服務器轉發給用戶PrintWriter printWriter = resp.getWriter();printWriter.print(picAndTextMsg2Xml);

該部分所有操作源碼,可以直接使用

CoreServlet.java(包括服務器接入、接收用戶發送消息、回復普通文字消息、回復圖文消息。需要第三方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"; /*  * 第二步:驗證服務器地址的有效性 開發者提交信息后,微信服務器將發送GET請求到填寫的服務器地址URL上,  * GET請求攜帶四個參數:signature、timestamp、nonce、echostr  * 開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。 若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,  * 則接入生效, 成為開發者成功,否則接入失敗。  *   * 加密/校驗流程如下: 1. 將token、timestamp、nonce三個參數進行字典序排序 2.  * 將三個參數字符串拼接成一個字符串進行sha1加密 3. 開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信  */ /*  * 字典排序(lexicographical  * order)是一種對于隨機變量形成序列的排序方法。其方法是,按照字母順序,或者數字小大順序,由小到大的形成序列。  */ @Override protected 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 block   e.printStackTrace();  }  digest.update(parmsString.getBytes());  byte messageDigest[] = digest.digest();  // Create Hex String  StringBuffer 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請求來自微信服務器,請原樣返回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("我是服務器回復給用戶的信息");  //  // // // 第二步,將構造的信息轉化為微信識別的xml格式【百度:xstream bean轉xml】  // XStream xStream = new XStream();  // xStream.alias("xml", textMsg.getClass());  // String textMsg2Xml = xStream.toXML(textMsg);  // System.out.println(textMsg2Xml);  //  // // // 第三步,發送xml的格式信息給微信服務器,服務器轉發給用戶  // 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的格式信息給微信服務器,服務器轉發給用戶  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; @Override public 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; @Override public 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; @Override public 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; }}

更多精彩內容請點擊《Android微信開發教程匯總》,《java微信開發教程匯總》歡迎大家學習閱讀。

以上就是本文的全部內容,希望對大家學習開java微信API有所幫助,也希望大家繼續關注新內容的更新,不要錯過哦!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 察隅县| 阿瓦提县| 健康| 洪洞县| 西吉县| 贺兰县| 年辖:市辖区| 留坝县| 江西省| 乌拉特中旗| 井陉县| 奈曼旗| 北安市| 呼和浩特市| 垦利县| 长泰县| 襄汾县| 留坝县| 潜山县| 山阴县| 全南县| 汉阴县| 册亨县| 泽库县| 南昌市| 巴彦淖尔市| 绥德县| 鄂托克前旗| 民县| 陈巴尔虎旗| 梧州市| 英超| 巢湖市| 合水县| 广东省| 永年县| 吴堡县| 藁城市| 晋中市| 浙江省| 咸丰县|