版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 . . 58/58微信公眾平臺(tái)開發(fā)教程Java版環(huán)境準(zhǔn)備篇準(zhǔn)備寫系列博客,記錄下我的微信公眾平臺(tái)學(xué)習(xí)記錄,也為那些摸索中的開發(fā)者提供點(diǎn)參考。希望與大家共同進(jìn)步。微信3.0的時(shí)候我開始做微信公眾賬號(hào),那時(shí)候沒時(shí)間研究開發(fā),先用的是編輯者模式,后用開發(fā)者模式,托管于第三方。一直想自己寫個(gè)服務(wù)端來實(shí)現(xiàn)個(gè)人定制化的需求。廢話不多說,進(jìn)入正題。想要開發(fā)微信公眾平臺(tái)需要一些環(huán)境一、申請(qǐng)微信公眾賬號(hào) 這個(gè)就不用廢話了。附上地址: s:/mp.weixin. ./cgi-bin/readtemplate?t=wxm2-realname-reg_tmpl&lang=zh_CN 現(xiàn)在申請(qǐng)好嚴(yán)格的說,3.0的時(shí)候
2、申請(qǐng)都不需要拍照什么的。 友情提示: 1、微信公眾賬號(hào)的名字一旦申請(qǐng),則不能更改。取名請(qǐng)慎重!2、一個(gè)只能申請(qǐng)兩個(gè)公眾號(hào) 3、公眾號(hào)分兩種:訂閱號(hào)和服務(wù)號(hào) 訂閱號(hào)可一天群發(fā)一次消息,目前不能申請(qǐng)自定義菜單。發(fā)送的消息將顯示在“訂閱號(hào)”文件夾中,適合媒體等提供咨詢服務(wù)的公眾號(hào)。 服務(wù)號(hào)一個(gè)月只能群發(fā)一條消息,能申請(qǐng)自定義菜單,發(fā)送的消息會(huì)顯示在用戶的聊天列表中,并會(huì)提醒用戶新消息。適合為用戶提供服務(wù)的公眾號(hào)二、外網(wǎng)服務(wù)器 你需要一臺(tái)外網(wǎng)服務(wù)器,來發(fā)布你的代碼,用于接收處理用戶發(fā)送的請(qǐng)求。 如果沒有的話,也不用擔(dān)心??梢允褂冒俣菳AE,或者是sina sae,國外比較多的是用google的gae。
3、 google gae支持的語言很多。但是在國經(jīng)常訪問不了,不推薦使用。 百度Bae 支持java和php(完全免費(fèi),百度對(duì)于資源方面還是一向很大方的,贊一個(gè),哈哈) sina sae 支持java,php,python(可免費(fèi)使用半年,收費(fèi)的,但很便宜)三、至少會(huì)一種語言 java,php,asp,python等,至少得會(huì)一樣!接下來的文章中我會(huì)用java做事例來做微信公眾平臺(tái)的開發(fā) HYPERLINK :/ /mobile/1515667.html t _blank 接口配置微信公眾賬號(hào)申請(qǐng)完成后,默認(rèn)開啟的是編輯模式。我們需要修改為開發(fā)模式。登陸微信公眾平臺(tái)功能高級(jí)功能先關(guān)閉 編輯模式,
4、再開啟 開發(fā)模式。申請(qǐng)成為開發(fā)者,如果是服務(wù)號(hào),需要?jiǎng)t會(huì)有開發(fā)者憑證信息如圖如果是訂閱號(hào),則只顯示服務(wù)器配置。下一步就是配置接口服務(wù)器了。在公眾平臺(tái)的高級(jí)功能 開發(fā)模式頁,點(diǎn)擊“成為開發(fā)者”按鈕,填寫URL和Token,其中URL是開發(fā)者用來接收微信服務(wù)器數(shù)據(jù)的接口URL。(這就是我們開發(fā)的程序,并部署到公網(wǎng)上了)Token 官網(wǎng)描述:可由開發(fā)者任意填寫,用作生成簽名(該Token會(huì)和接口URL中包含的Token進(jìn)行比對(duì),從而驗(yàn)證安全性)??傊褪悄愕某绦蚶锩鎸懙膖oken和這里填入的token要一致。還沒有url和token?首先需要新建一個(gè)java web工程。接下來就要看看驗(yàn)證url和t
5、oken了。下面是官網(wǎng)的描述,已經(jīng)寫的很清楚了核心實(shí)現(xiàn)方式就是將三個(gè)參數(shù)排序,拼接成字符串進(jìn)行sha1加密,然后與signature比較官網(wǎng)也給了實(shí)例,是php的,我們只需要裝換成java就可以了。private function checkSignature() $signature = $_GETsignature; $timestamp = $_GETtimestamp; $nonce = $_GETnonce;$token = TOKEN;$tmpArr = array($token, $timestamp, $nonce);sort($tmpArr);$tmpStr = implod
6、e( $tmpArr );$tmpStr = sha1( $tmpStr );if( $tmpStr = $signature )return true;elsereturn false;java代碼 我的 WeixinController 類 我的項(xiàng)目架構(gòu)是基于spring3.0的,用到了注解。當(dāng)get請(qǐng)求的時(shí)候會(huì)執(zhí)行g(shù)et方法,post請(qǐng)求的時(shí)候會(huì)執(zhí)行post方法,分別來處理不同的請(qǐng)求,各位也可用servlet等去實(shí)現(xiàn),原理都一樣package .ifp.weixin.controller;import java.io.IOException;import java.io.PrintWri
7、ter;import java.io.UnsupportedEncodingException;import javax.annotation.Resource;import javax.servlet. . ServletRequest;import javax.servlet. . ServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.we
8、b.bind.annotation.RequestMethod;import .core.CoreService;import .ifp.weixin.util.SignUtil;ControllerRequestMapping(/weixinCore)public class WeixinController Resource(name=coreService)private CoreService coreService;RequestMapping(method = RequestMethod.GET)public void get( ServletRequest request, Se
9、rvletResponse response) / 微信加密簽名,signature結(jié)合了開發(fā)者填寫的token參數(shù)和請(qǐng)求中的timestamp參數(shù)、nonce參數(shù)。String signature = request.getParameter(signature);/ 時(shí)間戳String timestamp = request.getParameter(timestamp);/ 隨機(jī)數(shù)String nonce = request.getParameter(nonce);/ 隨機(jī)字符串String echostr = request.getParameter(echostr);PrintWri
10、ter out = null;try out = response.getWriter();/ 通過檢驗(yàn)signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),若校驗(yàn)成功則原樣返回echostr,否則接入失敗if (SignUtil.checkSignature(signature, timestamp, nonce) out.print(echostr); catch (IOException e) e.printStackTrace(); finally out.close();out = null;RequestMapping(method = RequestMethod.POST)public void p
11、ost( ServletRequest request, ServletResponse response) /暫時(shí)空著,在這里可處理用戶請(qǐng)求上面類中用到了SignUtil 類package .ifp.weixin.util;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Arrays;import .ifp.weixin.constant.Constant;/* * 驗(yàn)證簽名 * */public class SignUtil /* * 驗(yàn)證簽名
12、 * param signature * param timestamp * param nonce * return */public static boolean checkSignature(String signature, String timestamp, String nonce) String arr = new String Constant.TOKEN, timestamp, nonce ;/ 將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典排序Arrays.sort(arr);StringBuilder content = new StringBuilder(
13、);for (int i = 0; i arr.length; i+) content.append(arri);MessageDigest md = null;String tmpStr = null;try md = MessageDigest.getInstance(SHA-1);/ 將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密byte digest = md.digest(content.toString().getBytes();tmpStr = byteToStr(digest); catch (NoSuchAlgorithmException e) e.printStackT
14、race();content = null;/ 將sha1加密后的字符串可與signature對(duì)比return tmpStr != null ? tmpStr.equals(signature.toUpperCase() : false;/* * 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串 * * param byteArray * return*/private static String byteToStr(byte byteArray) String strDigest = ;for (int i = 0; i 4) & 0X0F;tempArr1 = DigitmByte & 0X0F;Strin
15、g s = new String(tempArr);return s;我們看到checkSignature 這個(gè)方法里使用到了Constant.TOKEN ,這個(gè)token,我聲明的一個(gè)常量。要與微信配置接口里面的token值一樣/* 與接口配置信息中的Token要一致*/public static String TOKEN = infopower;也貼上web.xml的配置,我的后綴是.html 的請(qǐng)求都交給DispatcherServlet了。weixinHelpcontextConfigLocationclasspath:/applicationContext.xmllog4jConfi
16、gLocationclasspath:/properties/pertiesorg.springframework.web.util.Log4jConfigListenerencodingFilterorg.springframework.web.filter.CharacterEncodingFilterencodingUTF-8encodingFilter/*spring 容器的監(jiān)聽器org.springframework.web.context.ContextLoaderListeneractionorg.springframework.web.servlet.DispatcherSer
17、vletaction*.htmlindex.jsp我們的代碼已經(jīng)寫完了,訪問請(qǐng)求地址試試什么都沒有顯示,看看后臺(tái)報(bào)空指針異常別擔(dān)心,我們的代碼沒問題。因?yàn)橹苯釉L問地址,默認(rèn)是get請(qǐng)求,而什么參數(shù)都沒有傳給后臺(tái),當(dāng)然會(huì)報(bào)空指針前臺(tái)沒有異常,是因?yàn)槲易隽水惓L幚怼k接下來就是把代碼打成war包發(fā)布到外網(wǎng)。然后填入相應(yīng)的url和token,接口的配置就完成了。注意1:一定要發(fā)布war包到外網(wǎng),配置外網(wǎng)的url,有些開發(fā)者配置的是ip是localhost,那肯定是不行的啦。 如果沒有外網(wǎng)環(huán)境,請(qǐng)看我的第一篇,環(huán)境準(zhǔn)備,里面有介紹可以使用百度baetuposky.iteye./blog/200858
18、3注意2:開發(fā)模式一定要開啟,不然配置了url和token也沒用,我犯過這個(gè)錯(cuò),嘿嘿。 HYPERLINK :/ /mobile/1518537.html t _blank 消息接收和發(fā)送前面兩章已經(jīng)介紹了如何接入微信公眾平臺(tái),這一章說說消息的接收和發(fā)送可以先了解公眾平臺(tái)的消息api接口(接收消息,發(fā)送消息)mp.weixin. ./wiki/index.php接收消息當(dāng)普通微信用戶向公眾賬號(hào)發(fā)消息時(shí),微信服務(wù)器將POST消息的XML數(shù)據(jù)包到開發(fā)者填寫的URL上。mp.weixin. ./wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%8
19、0%9A%E6%B6%88%E6%81%AF接收的消息類型有6種,分別為:1文本消息2圖片消息3語音消息4視頻消息5地理位置消息6消息可以根據(jù)官方的api提供的字段建立對(duì)應(yīng)的實(shí)體類如:文本消息有很多屬性是所有消息類型都需要的,可以把這些信息提取出來建立一個(gè)基類package .ifp.weixin.entity.Message.req;/* * 消息基類(用戶 - 公眾) * */public class BaseMessage /* * 開發(fā)者微信號(hào) */private String ToUserName;/* * 發(fā)送方(一個(gè)OpenID) */private String FromUse
20、rName;/* * 消息創(chuàng)建時(shí)間 (整型) */private long CreateTime;/* * 消息類型 text、image、location、link */private String MsgType;/* * 消息id,64位整型 */private long MsgId;public String getToUserName() return ToUserName;public void setToUserName(String toUserName) ToUserName = toUserName;public String getFromUserName() retur
21、n 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 = msgT
22、ype;public long getMsgId() return MsgId;public void setMsgId(long msgId) MsgId = msgId;接收的文本消息package .ifp.weixin.entity.Message.req;/* * 文本消息 */public class TextMessage extends BaseMessage /* * 回復(fù)的消息容 */private String Content;public String getContent() return Content;public void setContent(String c
23、ontent) Content = content;接收的圖片消息package .ifp.weixin.entity.Message.req;public class ImageMessage extends BaseMessageprivate String picUrl;public String getPicUrl() return picUrl;public void setPicUrl(String picUrl) this.picUrl = picUrl;接收的消息package .ifp.weixin.entity.Message.req;public class LinkMe
24、ssage extends BaseMessage /* * 消息標(biāo)題 */private String Title;/* * 消息描述 */private String Description;/* * 消息 */private String Url;public String getTitle() return Title;public void setTitle(String title) Title = title;public String getDescription() return Description;public void setDescription(String de
25、scription) Description = description;public String getUrl() return Url;public void setUrl(String url) Url = url;接收的語音消息package .ifp.weixin.entity.Message.req;/* * 語音消息 * * author Caspar * */public class VoiceMessage extends BaseMessage /* * 媒體ID */private String MediaId;/* * 語音格式 */private String Fo
26、rmat;public String getMediaId() return MediaId;public void setMediaId(String mediaId) MediaId = mediaId;public String getFormat() return Format;public void setFormat(String format) Format = format;接收的地理位置消息package .ifp.weixin.entity.Message.req;/* * 位置消息 * * author caspar * */public class LocationMe
27、ssage extends BaseMessage /* * 地理位置維度 */private String Location_X;/* * 地理位置經(jīng)度 */private String Location_Y;/* * 地圖縮放大小 */private String Scale;/* * 地理位置信息 */private String Label;public String getLocation_X() return Location_X;public void setLocation_X(String location_X) Location_X = location_X;public
28、String getLocation_Y() return Location_Y;public void setLocation_Y(String location_Y) Location_Y = location_Y;public String getScale() return Scale;public void setScale(String scale) Scale = scale;public String getLabel() return Label;public void setLabel(String label) Label = label;發(fā)送被動(dòng)響應(yīng)消息對(duì)于每一個(gè)POS
29、T請(qǐng)求,開發(fā)者在響應(yīng)包(Get)中返回特定XML結(jié)構(gòu),對(duì)該消息進(jìn)行響應(yīng)(現(xiàn)支持回復(fù)文本、圖片、圖文、語音、視頻、音樂)。請(qǐng)注意,回復(fù)圖片等多媒體消息時(shí)需要預(yù)先上傳多媒體文件到微信服務(wù)器,只支持認(rèn)證服務(wù)號(hào)。同樣,建立響應(yīng)消息的對(duì)應(yīng)實(shí)體類 也把公共的屬性提取出來,封裝成基類 響應(yīng)消息的基類package .ifp.weixin.entity.Message.resp;/* * 消息基類(公眾 - 用戶) */public class BaseMessage /* * 接收方(收到的OpenID) */private String ToUserName;/* * 開發(fā)者微信號(hào) */private S
30、tring FromUserName;/* * 消息創(chuàng)建時(shí)間 (整型) */private long CreateTime;/* * 消息類型 */private String MsgType;/* * 位0 x0001被標(biāo)志時(shí),星標(biāo)剛收到的消息 */private int FuncFlag;public String getToUserName() return ToUserName;public void setToUserName(String toUserName) ToUserName = toUserName;public String getFromUserName() retu
31、rn 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 = msg
32、Type;public int getFuncFlag() return FuncFlag;public void setFuncFlag(int funcFlag) FuncFlag = funcFlag; 響應(yīng)文本消息package .ifp.weixin.entity.Message.resp;/* * 文本消息 */public class TextMessage extends BaseMessage /* * 回復(fù)的消息容 */private String Content;public String getContent() return Content;public void s
33、etContent(String content) Content = content;響應(yīng)圖文消息package .ifp.weixin.entity.Message.resp;import java.util.List;/* * 多圖文消息, * 單圖文的時(shí)候 Articles 只放一個(gè)就行了 * author Caspar.chen */public class NewsMessage extends BaseMessage /* * 圖文消息個(gè)數(shù),限制為10條以 */private int ArticleCount;/* * 多條圖文消息信息,默認(rèn)第一個(gè)item為大圖 */privat
34、e List Articles;public int getArticleCount() return ArticleCount;public void setArticleCount(int articleCount) ArticleCount = articleCount;public List getArticles() return Articles;public void setArticles(List articles) Articles = articles;圖文消息的定義package .ifp.weixin.entity.Message.resp;/* * 圖文消息 * *
35、/public class Article /* * 圖文消息名稱 */private String Title;/* * 圖文消息描述 */private String Description;/* * 圖片,支持JPG、PNG格式, * 較好的效果為大圖640*320,小圖80*80 */private String PicUrl;/* * 點(diǎn)擊圖文消息跳轉(zhuǎn) */private String Url;public String getTitle() return Title;public void setTitle(String title) Title = title;public St
36、ring getDescription() return null = Description ? : Description;public void setDescription(String description) Description = description;public String getPicUrl() return null = PicUrl ? : PicUrl;public void setPicUrl(String picUrl) PicUrl = picUrl;public String getUrl() return null = Url ? : Url;pub
37、lic void setUrl(String url) Url = url;響應(yīng)音樂消息package .ifp.weixin.entity.Message.resp;/* * 音樂消息 */public class MusicMessage extends BaseMessage /* * 音樂 */private Music Music;public Music getMusic() return Music;public void setMusic(Music music) Music = music;音樂消息的定義package .ifp.weixin.entity.Message.r
38、esp;/* * 音樂消息 */public class Music /* * 音樂名稱 */private String Title;/* * 音樂描述 */private String Description;/* * 音樂 */private String MusicUrl;/* * 高質(zhì)量音樂,WIFI環(huán)境優(yōu)先使用該播放音樂 */private String HQMusicUrl;public String getTitle() return Title;public void setTitle(String title) Title = title;public String get
39、Description() 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
40、) HQMusicUrl = musicUrl;構(gòu)建好之后的項(xiàng)目結(jié)構(gòu)圖為到這里,請(qǐng)求消息和響應(yīng)消息的實(shí)體類都定義好了解析請(qǐng)求消息用戶向微信公眾平臺(tái)發(fā)送消息后,微信公眾平臺(tái)會(huì)通過post請(qǐng)求發(fā)送給我們。上一章中WeixinController 類的post方法我們空著現(xiàn)在我們要在這里處理用戶請(qǐng)求了。因?yàn)槲⑿诺陌l(fā)送和接收都是用xml格式的,所以我們需要處理請(qǐng)求過來的xml格式。發(fā)送的時(shí)候也需要轉(zhuǎn)化成xml格式再發(fā)送給微信,所以封裝了消息處理的工具類,用到dome4j和xstream兩個(gè)jar包package .ifp.weixin.util;import java.io.InputStream;i
41、mport java.io.Writer;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet. . ServletRequest;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import .ifp.weixin.entity.Message.resp.Article;import .ifp.weixin.entity.Message.resp.Music
42、Message;import .ifp.weixin.entity.Message.resp.NewsMessage;import .ifp.weixin.entity.Message.resp.TextMessage;import .thoughtworks.xstream.XStream;import .thoughtworks.xstream.core.util.QuickWriter;import .thoughtworks.xstream.io.HierarchicalStreamWriter;import .thoughtworks.xstream.io.xml.PrettyPri
43、ntWriter;import .thoughtworks.xstream.io.xml.XppDriver;/* * 消息工具類 * */public class MessageUtil /* * 解析微信發(fā)來的請(qǐng)求(XML) * * param request * return * throws Exception */public static Map parseXml( ServletRequest request) throws Exception / 將解析結(jié)果存儲(chǔ)在HashMap中Map map = new HashMap();/ 從request中取得輸入流InputStrea
44、m inputStream = request.getInputStream();/ 讀取輸入流SAXReader reader = new SAXReader();Document document = reader.read(inputStream);/ 得到xml根元素Element root = document.getRootElement();/ 得到根元素的所有子節(jié)點(diǎn)SuppressWarnings(unchecked)List elementList = root.elements();/ 遍歷所有子節(jié)點(diǎn)for (Element e : elementList)map.put(
45、e.getName(), e.getText();/ 釋放資源inputStream.close();inputStream = null;return map;/* * 文本消息對(duì)象轉(zhuǎn)換成xml * * param textMessage 文本消息對(duì)象 * return xml */public static String textMessageToXml(TextMessage textMessage) xstream.alias(xml, textMessage.getClass();return xstream.toXML(textMessage);/* * 音樂消息對(duì)象轉(zhuǎn)換成xml
46、* * param musicMessage 音樂消息對(duì)象 * return xml */public static String musicMessageToXml(MusicMessage musicMessage) xstream.alias(xml, musicMessage.getClass();return xstream.toXML(musicMessage);/* * 圖文消息對(duì)象轉(zhuǎn)換成xml * * param newsMessage 圖文消息對(duì)象 * return xml */public static String newsMessageToXml(NewsMessage
47、 newsMessage) xstream.alias(xml, newsMessage.getClass();xstream.alias(item, new Article().getClass();return xstream.toXML(newsMessage);/* * 擴(kuò)展xstream,使其支持CDATA塊 * */private static XStream xstream = new XStream(new XppDriver() public HierarchicalStreamWriter createWriter(Writer out) return new Pretty
48、PrintWriter(out) / 對(duì)所有xml節(jié)點(diǎn)的轉(zhuǎn)換都增加CDATA標(biāo)記boolean cdata = true;protected void writeText(QuickWriter writer, String text) if (cdata) writer.write(); else writer.write(text););接下來在處理業(yè)務(wù)邏輯,建立一個(gè)接收并響應(yīng)消息的service類,并針對(duì)用戶輸入的1或2回復(fù)不同的信息給用戶package .core.impl;import java.util.Date;import java.util.Map;import javax.
49、servlet. . ServletRequest;import org.apache.log4j.Logger;import org.springframework.stereotype.Service;import .core.CoreService;import .ifp.weixin.constant.Constant;import .ifp.weixin.entity.Message.resp.TextMessage;import .ifp.weixin.util.MessageUtil;Service(coreService)public class CoreServiceImpl
50、 implements CoreServicepublic static Logger log = Logger.getLogger(CoreServiceImpl.class);Overridepublic String processRequest( ServletRequest request) String respMessage = null;try / xml請(qǐng)求解析Map requestMap = MessageUtil.parseXml(request);/ 發(fā)送方(open_id)String fromUserName = requestMap.get(FromUserNam
51、e);/ 公眾String toUserName = requestMap.get(ToUserName);/ 消息類型String msgType = requestMap.get(MsgType);TextMessage textMessage = new TextMessage();textMessage.setToUserName(fromUserName);textMessage.setFromUserName(toUserName);textMessage.setCreateTime(new Date().getTime();textMessage.setMsgType(Const
52、ant.RESP_MESSAGE_TYPE_TEXT);textMessage.setFuncFlag(0);/ 文本消息if (msgType.equals(Constant.REQ_MESSAGE_TYPE_TEXT) / 接收用戶發(fā)送的文本消息容String content = requestMap.get(Content);if (1.equals(content) textMessage.setContent(1是很好的);/ 將文本消息對(duì)象轉(zhuǎn)換成xml字符串respMessage = MessageUtil.textMessageToXml(textMessage);else if
53、 (2.equals(content) textMessage.setContent(我不是2貨);/ 將文本消息對(duì)象轉(zhuǎn)換成xml字符串respMessage = MessageUtil.textMessageToXml(textMessage); catch (Exception e) e.printStackTrace();return respMessage;接下來在controller里面的post方法里面調(diào)用即可WeixinController類的完整代碼package .ifp.weixin.controller;import java.io.IOException;import
54、java.io.PrintWriter;import java.io.UnsupportedEncodingException;import javax.annotation.Resource;import javax.servlet. . ServletRequest;import javax.servlet. . ServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.sp
55、ringframework.web.bind.annotation.RequestMethod;import .core.CoreService;import .ifp.weixin.util.SignUtil;ControllerRequestMapping(/weixinCore)public class WeixinController Resource(name=coreService)private CoreService coreService;RequestMapping(method = RequestMethod.GET)public void get( ServletReq
56、uest request, ServletResponse response) / 微信加密簽名,signature結(jié)合了開發(fā)者填寫的token參數(shù)和請(qǐng)求中的timestamp參數(shù)、nonce參數(shù)。String signature = request.getParameter(signature);/ 時(shí)間戳String timestamp = request.getParameter(timestamp);/ 隨機(jī)數(shù)String nonce = request.getParameter(nonce);/ 隨機(jī)字符串String echostr = request.getParameter(e
57、chostr);PrintWriter out = null;try out = response.getWriter();/ 通過檢驗(yàn)signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),若校驗(yàn)成功則原樣返回echostr,否則接入失敗if (SignUtil.checkSignature(signature, timestamp, nonce) out.print(echostr); catch (IOException e) e.printStackTrace(); finally out.close();out = null;RequestMapping(method = RequestMethod.PO
58、ST)public void post( ServletRequest request, ServletResponse response) try request.setCharacterEncoding(UTF-8); catch (UnsupportedEncodingException e) e.printStackTrace();response.setCharacterEncoding(UTF-8);/ 調(diào)用核心業(yè)務(wù)類接收消息、處理消息String respMessage = coreScessRequest(request);/ 響應(yīng)消息PrintWriter out = nul
59、l;try out = response.getWriter();out.print(respMessage); catch (IOException e) e.printStackTrace(); finally out.close();out = null;效果如下:ok,大功告成,消息的接收和發(fā)送就寫完了。 HYPERLINK :/ /mobile/1518520.html t _blank 圖文消息引言:上一章講到了消息的接收和發(fā)送,但是講的是最簡單的文本信息。在微信中用的最多的信息還是圖文消息,本章就為大家講解下微信圖文消息是如何實(shí)現(xiàn)的。包括單圖文和多圖文消息。圖文消息的XML數(shù)據(jù)包
60、結(jié)構(gòu):Xml代碼123456782 從上面結(jié)構(gòu)圖中可以看出要注意的幾點(diǎn)1、圖文消息的條數(shù)最大限制為10,2、多圖文中列表中的第一個(gè)為大圖,其余為小圖注意:在多圖文模式下只有第一個(gè)可以顯示描述信息,其余的都不顯示了解了圖文消息的結(jié)構(gòu)后,要發(fā)送圖文消息就簡單了。我們之前已經(jīng)封裝過消息處理的代碼和圖文消息的實(shí)體類,這里就不啰嗦了,不知道的可以看上一章HYPERLINK :/tuposky.iteye /admin/blogs/2017429 o 微信公眾平臺(tái)開發(fā)教程Java版(三) 消息接收和發(fā)送 t _blank微信公眾平臺(tái)開發(fā)教程Java版(三) 消息接收和發(fā)送下面我就上單圖文和多圖文消息的源代
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 貴州大學(xué)《電動(dòng)汽車動(dòng)力電池與能源管理》2023-2024學(xué)年第一學(xué)期期末試卷
- 貴陽學(xué)院《中法跨文化交際》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025天津市建筑安全員-C證(專職安全員)考試題庫
- 2025年河南建筑安全員《B證》考試題庫
- 2025年四川建筑安全員B證考試題庫附答案
- 2025江西省安全員考試題庫
- 廣州幼兒師范高等??茖W(xué)校《公共管理與服務(wù)課程開發(fā)與教材分析》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣州新華學(xué)院《軟件工程與實(shí)踐》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025湖南建筑安全員《C證》考試題庫
- 2025年江蘇省建筑安全員知識(shí)題庫附答案
- 2024國有企業(yè)與民營企業(yè)之間的混合所有制改革合同
- 物流倉庫安全生產(chǎn)
- 2024年醫(yī)院食堂餐飲獨(dú)家承包協(xié)議
- 保險(xiǎn)公司廉政風(fēng)險(xiǎn)防控制度
- DB34T4868-2024智慧醫(yī)院醫(yī)用耗材院內(nèi)物流規(guī)范
- 2025年蛇年年會(huì)匯報(bào)年終總結(jié)大會(huì)模板
- 《稻草人》閱讀題及答案
- 國家職業(yè)技術(shù)技能標(biāo)準(zhǔn) X2-10-07-17 陶瓷產(chǎn)品設(shè)計(jì)師(試行)勞社廳發(fā)200633號(hào)
- 瑜伽基礎(chǔ)知識(shí)題庫單選題100道及答案解析
- 廣東省廣州市2024年中考數(shù)學(xué)真題試卷(含答案)
- 落實(shí)《中小學(xué)德育工作指南》制定的實(shí)施方案(pdf版)
評(píng)論
0/150
提交評(píng)論