這篇文章主要為大家分析java微信開發(fā)API第二步驟取得與回覆訊息,有興趣的夥伴們可以參考一下
微信開發(fā)API如何取得與回復(fù)訊息,以下就為大家介紹
一、說明
* 本範(fàn)例根據(jù)微信開發(fā)文件:http://mp.weixin.qq.com/wiki /home/index.html最新版(4/3/2016 5:34:36 PM )進(jìn)行開發(fā)示範(fàn)。
* 編輯平臺:myeclipse10.7+win32+jdk1.7+tomcat7.0?
* 伺服器:阿里雲(yún)windows server 2008 64bits
* 平臺需求:servlet使用註解方式,##平臺需求:j2ee6.0+、jdk6.0+、tomcat7.0+
* 演示更著重於api解析。
* 為了便於測試說明,每個測試案例為獨(dú)立,不依賴其它方法。對於封裝,不多加考慮。
* 示範(fàn)盡可能依照API要求進(jìn)行,目的:了解文件使用方式,達(dá)到舉一反三的效果。
* 知識需求:強(qiáng)大的java基礎(chǔ)、了解http網(wǎng)路通訊知識、對於javaweb有足夠了解、json解析
* 在每篇文章結(jié)束會給出該部分演示原始碼。在分析完API之後,會以源碼包的形式給出所有演示源碼。
* 目前時間:4/3/2016 5:32:57 PM ,以該時間為準(zhǔn)。
二、文件原文-訊息管理(摘要)
#??文件位址:http://mp.weixin.qq .com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
??訊息管理
??接收訊息-接收普通訊息
??訊息管理
??接收訊息-接收普通訊息-接收事件推播
??傳送訊息-被動回覆訊息
??傳送訊息-被動回覆時的加解密
??傳送訊息-客服訊息
??傳送訊息-群發(fā)介面
??傳送訊息-範(fàn)本訊息運(yùn)作規(guī)格??取得公眾號自動回覆設(shè)定
?三、文件瞭解
##?接收訊息?文件這樣解釋:當(dāng)普通微信使用者向公眾帳號發(fā)送訊息時,微信伺服器將POST訊息的
XML
封包到開發(fā)者填寫的URL上。
??理解:微信伺服器將使用者傳送的訊息透過Post流的形式傳回給req。當(dāng)我們想要取得用戶發(fā)送的訊息時,可以透過req.getInputStream()取得。當(dāng)然,我們可以根據(jù)文件上關(guān)於訊息的傳回的xml格式,進(jìn)行必要的解析。
實(shí)作:/*
* 該部分我們獲取用戶發(fā)送的信息,并且解析成<K,V>的形式進(jìn)行顯示
*/
// 解析用戶發(fā)送過來的信息
InputStream is = req.getInputStream();// 拿取請求流
// 將解析結(jié)果存儲在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 解析xml,將獲取到的返回結(jié)果xml進(jìn)行解析成我們習(xí)慣的文字信息
SAXReader reader = new SAXReader();// 第三方j(luò)ar: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();
// 得到根元素的所有子節(jié)點(diǎn)
List<Element> elementList = root.elements();
// 遍歷所有子節(jié)點(diǎn)
for (Element e : elementList)
map.put(e.getName(), e.getText());
// 測試輸出
Set<String> keySet = map.keySet();
// 測試輸出解析后用戶發(fā)過來的信息
System.out.println(TAG + ":解析用戶發(fā)送過來的信息開始");
for (String key : keySet) {
System.out.println(key + ":" + map.get(key));
}
System.out.println(TAG + ":解析用戶發(fā)送過來的信息結(jié)束");
?發(fā)送訊息?文件這樣解釋:當(dāng)使用者傳送訊息給公眾號碼時(或某一些特定的使用者操作引發(fā)的事件推送時),會產(chǎn)生一個POST請求,開發(fā)者可以在回應(yīng)包(Get)中返回特定XML結(jié)構(gòu),來對該訊息進(jìn)行回應(yīng)(現(xiàn)支援回覆文字、圖片、圖文、語音、
影片
、音樂)。嚴(yán)格來說,發(fā)送被動回應(yīng)訊息其實(shí)不是一種接口,而是對微信伺服器發(fā)過來訊息的回覆。
??實(shí)作1-回覆普通文字訊息:
//實(shí)例1:發(fā)送普通文本消息,請查看文檔關(guān)于“回復(fù)文本消息”的xml格式 // 第一步:按照回復(fù)文本信息構(gòu)造需要的參數(shù) TextMsg textMsg = new TextMsg(); textMsg.setToUserName(map.get("FromUserName"));// 發(fā)送和接收信息“User”剛好相反 textMsg.setFromUserName(map.get("ToUserName")); textMsg.setCreateTime(new Date().getTime());// 消息創(chuàng)建時間 (整型) textMsg.setMsgType("text");// 文本類型消息 textMsg.setContent("我是服務(wù)器回復(fù)給用戶的信息"); // // 第二步,將構(gòu)造的信息轉(zhuǎn)化為微信識別的xml格式【百度:xstream bean轉(zhuǎn)xml】 XStream xStream = new XStream(); xStream.alias("xml", textMsg.getClass()); String textMsg2Xml = xStream.toXML(textMsg); System.out.println(textMsg2Xml); // // 第三步,發(fā)送xml的格式信息給微信服務(wù)器,服務(wù)器轉(zhuǎn)發(fā)給用戶 PrintWriter printWriter = resp.getWriter(); printWriter.print(textMsg2Xml);
??實(shí)作2-回覆圖文訊息://實(shí)例2,發(fā)送圖文消息。請查看文檔關(guān)于“回復(fù)圖文消息”的xml格式
// 第一步:按照回復(fù)圖文信息構(gòu)造需要的參數(shù)
List<Article> articles = new ArrayList<Article>();
Article a = new Article();
a.setTitle("我是圖片標(biāo)題");
a.setUrl("www.baidu.com");// 該地址是點(diǎn)擊圖片跳轉(zhuǎn)后
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"));// 發(fā)送和接收信息“User”剛好相反
picAndTextMsg.setFromUserName(map.get("ToUserName"));
picAndTextMsg.setCreateTime(new Date().getTime());// 消息創(chuàng)建時間 (整型)
picAndTextMsg.setMsgType("news");// 圖文類型消息
picAndTextMsg.setArticleCount(1);
picAndTextMsg.setArticles(articles);
// 第二步,將構(gòu)造的信息轉(zhuǎn)化為微信識別的xml格式【百度:xstream bean轉(zhuǎn)xml】
XStream xStream = new XStream();
xStream.alias("xml", picAndTextMsg.getClass());
xStream.alias("item", a.getClass());
String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg);
System.out.println(picAndTextMsg2Xml);
// 第三步,發(fā)送xml的格式信息給微信服務(wù)器,服務(wù)器轉(zhuǎn)發(fā)給用戶
PrintWriter printWriter = resp.getWriter();
printWriter.print(picAndTextMsg2Xml);
這部分所有操作原始碼,可以直接使用
??CoreServlet.java(包括伺服器存取、接收使用者傳送訊息、回覆一般文字訊息、回覆圖文訊息。需要第三方j(luò)ar: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 高遠(yuǎn)</n> 郵箱:wgyscsf@163.com</n> 博客 http://ipnx.cn/;/n> * 編寫時期 2016-4-3 下午4:34:05 */ @WebServlet("/CoreServlet") public class CoreServlet extends HttpServlet { private static final long serialVersionUID = 1L; String TAG = "CoreServlet"; /* * 第二步:驗(yàn)證服務(wù)器地址的有效性 開發(fā)者提交信息后,微信服務(wù)器將發(fā)送GET請求到填寫的服務(wù)器地址URL上, * GET請求攜帶四個參數(shù):signature、timestamp、nonce、echostr * 開發(fā)者通過檢驗(yàn)signature對請求進(jìn)行校驗(yàn)(下面有校驗(yàn)方式)。 若確認(rèn)此次GET請求來自微信服務(wù)器,請?jiān)瓨臃祷豦chostr參數(shù)內(nèi)容, * 則接入生效, 成為開發(fā)者成功,否則接入失敗。 * * 加密/校驗(yàn)流程如下: 1. 將token、timestamp、nonce三個參數(shù)進(jìn)行字典序排序 2. * 將三個參數(shù)字符串拼接成一個字符串進(jìn)行sha1加密 3. 開發(fā)者獲得加密后的字符串可與signature對比,標(biāo)識該請求來源于微信 */ /* * 字典排序(lexicographical * order)是一種對于隨機(jī)變量形成序列的排序方法。其方法是,按照字母順序,或者數(shù)字小大順序,由小到大的形成序列。 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 設(shè)置編碼 req.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); resp.setCharacterEncoding("utf-8"); // 獲取輸出流 PrintWriter printWriter = resp.getWriter(); // 設(shè)置一個全局的token,開發(fā)者自己設(shè)置。api這樣解釋:Token可由開發(fā)者可以任意填寫, // 用作生成簽名(該Token會和接口URL中包含的Token進(jìn)行比對,從而驗(yàn)證安全性) String token = "wgyscsf"; // 根據(jù)api說明,獲取上述四個參數(shù) String signature = req.getParameter("signature"); String timestamp = req.getParameter("timestamp"); String nonce = req.getParameter("nonce"); String echostr = req.getParameter("echostr"); // // temp:臨時打印,觀看返回參數(shù)情況 // System.out.println(TAG + ":signature:" + signature + ",timestamp:" // + timestamp + ",nonce:" + nonce + ",echostr:" + echostr); // 根據(jù)api所說的“加密/校驗(yàn)流程”進(jìn)行接入。共計(jì)三步 // 第一步:將token、timestamp、nonce三個參數(shù)進(jìn)行字典序排序 String[] parms = new String[] { token, timestamp, nonce };// 將需要字典序排列的字符串放到數(shù)組中 Arrays.sort(parms);// 按照api要求進(jìn)行字典序排序 // 第二步:將三個參數(shù)字符串拼接成一個字符串進(jìn)行sha1加密 // 拼接字符串 String parmsString = "";// 注意,此處不能=null。 for (int i = 0; i < parms.length; i++) { parmsString += parms[i]; } // sha1加密 String mParms = null;// 加密后的結(jié)果 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(); // 字節(jié)數(shù)組轉(zhuǎn)換為 十六進(jìn)制 數(shù) 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();// 加密結(jié)果 /* * api要求: 若確認(rèn)此次GET請求來自微信服務(wù)器,請?jiān)瓨臃祷豦chostr參數(shù)內(nèi)容, 則接入生效, 成為開發(fā)者成功,否則接入失敗。 */ // 第三步: 開發(fā)者獲得加密后的字符串可與signature對比,標(biāo)識該請求來源于微信接入成功。 // 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文檔關(guān)于收發(fā)消息推送的消息格式基本一致。 如以下格式: <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> 那么,我們就可以進(jìn)行統(tǒng)一處理。 */ /* * 我們先獲取輸入流,看輸入流里面的信息。通過測試打印輸出流,我們可以看到每次用戶請求,都會收到req請求,請求格式是xml格式,該信息在文檔中有說明。 */ /* * 特別注意,req.getInputStream()只能獲取一次,并且只能讀取一次。如果想要多次讀取,需要另外想辦法。為了簡單起見, * 我們只獲取一次req.getInputStream(),不再打印輸出流信息。直接打印解析后的信息。 */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 設(shè)置編碼 req.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); resp.setCharacterEncoding("utf-8"); /* * 該部分我們獲取用戶發(fā)送的信息,并且解析成<K,V>的形式進(jìn)行顯示 */ // 解析用戶發(fā)送過來的信息 InputStream is = req.getInputStream();// 拿取請求流 // 將解析結(jié)果存儲在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 解析xml,將獲取到的返回結(jié)果xml進(jìn)行解析成我們習(xí)慣的文字信息 SAXReader reader = new SAXReader();// 第三方j(luò)ar: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(); // 得到根元素的所有子節(jié)點(diǎn) List<Element> elementList = root.elements(); // 遍歷所有子節(jié)點(diǎn) for (Element e : elementList) map.put(e.getName(), e.getText()); // 測試輸出 Set<String> keySet = map.keySet(); // 測試輸出解析后用戶發(fā)過來的信息 System.out.println(TAG + ":解析用戶發(fā)送過來的信息開始"); for (String key : keySet) { System.out.println(key + ":" + map.get(key)); } System.out.println(TAG + ":解析用戶發(fā)送過來的信息結(jié)束"); /* * 該部分我們嘗試按照文檔的要求格式給用戶回復(fù)文本信息、圖文消息。重點(diǎn):按照文檔要求構(gòu)造需要的參數(shù)。特別注意:參數(shù)區(qū)分大小寫。 */ // //實(shí)例1:發(fā)送普通文本消息,請查看文檔關(guān)于“回復(fù)文本消息”的xml格式 // // // 第一步:按照回復(fù)文本信息構(gòu)造需要的參數(shù) // TextMsg textMsg = new TextMsg(); // textMsg.setToUserName(map.get("FromUserName"));// 發(fā)送和接收信息“User”剛好相反 // textMsg.setFromUserName(map.get("ToUserName")); // textMsg.setCreateTime(new Date().getTime());// 消息創(chuàng)建時間 (整型) // textMsg.setMsgType("text");// 文本類型消息 // textMsg.setContent("我是服務(wù)器回復(fù)給用戶的信息"); // // // // 第二步,將構(gòu)造的信息轉(zhuǎn)化為微信識別的xml格式【百度:xstream bean轉(zhuǎn)xml】 // XStream xStream = new XStream(); // xStream.alias("xml", textMsg.getClass()); // String textMsg2Xml = xStream.toXML(textMsg); // System.out.println(textMsg2Xml); // // // // 第三步,發(fā)送xml的格式信息給微信服務(wù)器,服務(wù)器轉(zhuǎn)發(fā)給用戶 // PrintWriter printWriter = resp.getWriter(); // printWriter.print(textMsg2Xml); // //實(shí)例2,發(fā)送圖文消息。請查看文檔關(guān)于“回復(fù)圖文消息”的xml格式 // 第一步:按照回復(fù)圖文信息構(gòu)造需要的參數(shù) List<Article> articles = new ArrayList<Article>(); Article a = new Article(); a.setTitle("我是圖片標(biāo)題"); a.setUrl("www.baidu.com");// 該地址是點(diǎn)擊圖片跳轉(zhuǎn)后 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"));// 發(fā)送和接收信息“User”剛好相反 picAndTextMsg.setFromUserName(map.get("ToUserName")); picAndTextMsg.setCreateTime(new Date().getTime());// 消息創(chuàng)建時間 (整型) picAndTextMsg.setMsgType("news");// 圖文類型消息 picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles); // 第二步,將構(gòu)造的信息轉(zhuǎn)化為微信識別的xml格式【百度:xstream bean轉(zhuǎn)xml】 XStream xStream = new XStream(); xStream.alias("xml", picAndTextMsg.getClass()); xStream.alias("item", a.getClass()); String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg); System.out.println(picAndTextMsg2Xml); // 第三步,發(fā)送xml的格式信息給微信服務(wù)器,服務(wù)器轉(zhuǎn)發(fā)給用戶 PrintWriter printWriter = resp.getWriter(); printWriter.print(picAndTextMsg2Xml); } }
??TestMsg.java(普通文字訊息bean)?
package com.gist.bean; /** * @author 高遠(yuǎn)</n> 郵箱:wgyscsf@163.com</n> 博客 http://ipnx.cn/;/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(圖文訊息內(nèi)部Article bean)
package com.gist.bean; /** * @author 高遠(yuǎn)</n> 郵箱:wgyscsf@163.com</n> 博客 http://ipnx.cn/;/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 高遠(yuǎn)</n> 郵箱:wgyscsf@163.com</n> 博客 http://ipnx.cn/;/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; } }
以上是分析java微信開發(fā)API第二步驟取得與回覆訊息的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)