java微信企業(yè)號(hào)開(kāi)發(fā)之發(fā)送消息(文本、圖片、語(yǔ)音)
上篇文章介紹了開(kāi)啟回調(diào)模式,開(kāi)始回調(diào)模式后我們就要實(shí)現(xiàn)聊天功能了。平時(shí)使用微信聊天可以發(fā)送文本消息、語(yǔ)音、圖片、視頻等,這里只實(shí)現(xiàn)了其中的一些功能和大家分享。
一、與微信企業(yè)號(hào)建立連接
1、企業(yè)應(yīng)用調(diào)用企業(yè)號(hào)提供的接口,管理或查詢企業(yè)號(hào)后臺(tái)所管理的資源、或給成員發(fā)送消息等,以下稱主動(dòng)調(diào)用模式。
2、企業(yè)號(hào)把用戶發(fā)送的消息或用戶觸發(fā)的事件推送給企業(yè)應(yīng)用,由企業(yè)應(yīng)用處理,以下稱回調(diào)模式。
3、用戶在微信中閱讀企業(yè)應(yīng)用下發(fā)的H5頁(yè)面,該頁(yè)面可以調(diào)用微信提供的原生接口,使用微信開(kāi)放的終端能力,以下稱JSAPI模式。
這是微信企業(yè)號(hào)的開(kāi)發(fā)文檔中寫的,但是我們一般使用前兩種方式。
其實(shí)主動(dòng)調(diào)用和回調(diào)都是相對(duì)的,這是站在微信服務(wù)器的角度,微信服務(wù)器通過(guò)企業(yè)號(hào)給微信客戶端發(fā)送消息是主動(dòng)調(diào)用,微信客戶端主動(dòng)發(fā)送消息去調(diào)用微信服務(wù)器相對(duì)服務(wù)器來(lái)說(shuō)就是被動(dòng)調(diào)用(回調(diào))。
二、主被動(dòng)調(diào)用微信服務(wù)器處理的數(shù)據(jù)格式
1.主調(diào):服務(wù)器向微信客戶端發(fā)送json格式的數(shù)據(jù),數(shù)據(jù)不需要加密
2.回調(diào):微信客戶端發(fā)送的消息需要AES加密,服務(wù)器接受的消息是xml格式
這兩條用一張圖表示如下:

三、聊天原理圖

首先微信客戶端發(fā)送消息到服務(wù)器處理,數(shù)據(jù)以xml格式傳輸?shù)降谌椒?wù)器后,第三方服務(wù)器再將數(shù)據(jù)轉(zhuǎn)為json格式,傳送給微信服務(wù)器,發(fā)送給客戶端。
四、代碼實(shí)現(xiàn)
有了上面的原理基礎(chǔ),下面是代碼部分
1.servlet
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String msg_signature = request.getParameter("msg_signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
InputStream inputStream = request.getInputStream();
String postData = IOUtils.toString(inputStream, "UTF-8");
System.out.println(postData);
String msg = "";
WXBizMsgCrypt wxcpt = null;
try {
wxcpt = new WXBizMsgCrypt(sToken , sEncodingAESKey , sCorpID );
msg = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData);
} catch (AesException e) {
e.printStackTrace();
}
System.out.println("msg=" + msg);
//獲取接口訪問(wèn)憑證
String accessToken = CommonUtil.getToken("wxe510946434680dab", "eWTaho766INvp4e1MCsz1mHYuT2DAleb62REQ3vsFizhY4vtmwZpKweuxUVh33G0").getAccessToken();
try {
@SuppressWarnings("unused")
boolean flag = ChatService1.sendMessage(accessToken,msg);
} catch (Exception e) {
e.printStackTrace();
}
}
2.service
public class ChatService1 {
public static boolean sendMessage(String accessToken,String msg) throws Exception{
boolean flag = false;
Map<String, String> requestMap = MessageUtil.parseXml(msg);
// 發(fā)送者
String fromUserName = requestMap.get("FromUserName");
// 消息類型
String msgType = requestMap.get("MsgType");
if(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)){//如果是文本客服消息
String Content = requestMap.get("Content");//文本消息的消息內(nèi)容
//組裝文本客服消息,參數(shù)1:用戶id;參數(shù)2:發(fā)送的內(nèi)容
jsonMsg = AdvancedUtil.makeTextCustomMessage("lishehe|zhisheng|zhangwenyuan|lixinjiang", Content);
}else if(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)){//發(fā)送的是圖片
String mediaId = requestMap.get("MediaId");
jsonMsg = AdvancedUtil.makeImageCustomMessage("lishehe|zhisheng|zhangwenyuan|lixinjiang", mediaId);
}else if(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){
String mediaId = requestMap.get("MediaId");
jsonMsg= AdvancedUtil.makeVoiceCustomMessage("lishehe|zhisheng|zhangwenyuan|lixinjiang", mediaId);
}
flag = AdvancedUtil.sendCustomMessage(accessToken, jsonMsg);
return flag;
}
}
3.工具類
public class AdvancedUtil {
private static Logger log = LoggerFactory.getLogger(AdvancedUtil.class);
/**
* 組裝發(fā)送文本消息
* @return
*/
public static String makeTextCustomMessage(String openId, String content) {
content = content.replace("\"", "\\\"");
String jsonMsg = "{\"touser\":\"%s\",\"msgtype\":\"text\",\"agentid\":\"%s\",\"text\":{\"content\":\"%s\"}}";
return String.format(jsonMsg, openId, 14,content);
}
/**
* 組裝發(fā)送圖片消息
*
* @return
*/
public static String makeImageCustomMessage(String openId, String mediaId) {
String jsonMsg = "{\"touser\":\"%s\",\"msgtype\":\"image\",\"agentid\":\"%s\",\"image\":{\"media_id\":\"%s\"}}";
return String.format(jsonMsg, openId,14, mediaId);
}
/**
* 組裝發(fā)送語(yǔ)音消息
*
* @return
*/
public static String makeVoiceCustomMessage(String openId, String mediaId) {
String jsonMsg = "{\"touser\":\"%s\",\"msgtype\":\"voice\",\"agentid\":\"%s\",\"voice\":{\"media_id\":\"%s\"}}";
return String.format(jsonMsg, openId,14, mediaId);
}
四、總結(jié)
這樣就實(shí)現(xiàn)了消息的接收和推送,第三方服務(wù)器將接受的xml數(shù)據(jù)先解密解析,從中獲取消息類型,然后將要發(fā)送的消息封裝后轉(zhuǎn)為json格式,并傳送給微信服務(wù)器在發(fā)送到客戶端。
本文已被整理到了《Android微信開(kāi)發(fā)教程匯總》,《java微信開(kāi)發(fā)教程匯總》歡迎大家學(xué)習(xí)閱讀。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)定時(shí)任務(wù)的示例代碼
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)定時(shí)任務(wù)的相關(guān)知識(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-11-11
java語(yǔ)言基礎(chǔ)之標(biāo)識(shí)符和命名規(guī)則詳解
這篇文章主要給大家介紹了關(guān)于java語(yǔ)言基礎(chǔ)之標(biāo)識(shí)符和命名規(guī)則的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
SpringBoot居然有44種應(yīng)用啟動(dòng)器,你都知道嗎
很多人都不知道SpringBoot應(yīng)用啟動(dòng)器竟然有44個(gè),本文就一起來(lái)介紹一下,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
JFinal使用ajaxfileupload實(shí)現(xiàn)圖片上傳及預(yù)覽
這篇文章主要為大家詳細(xì)介紹了JFinal使用ajaxfileupload實(shí)現(xiàn)圖片上傳及預(yù)覽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
ShardingSphere jdbc集成多數(shù)據(jù)源的實(shí)現(xiàn)步驟
本文主要介紹了ShardingSphere jdbc集成多數(shù)據(jù)源的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
使用java代碼實(shí)現(xiàn)保留小數(shù)點(diǎn)的位數(shù)
因?yàn)閭€(gè)人應(yīng)用的需要,所以就寫個(gè)簡(jiǎn)單點(diǎn)的了。希望大家都給給建議,共同學(xué)習(xí)。需要的朋友也可以參考下2013-07-07
解決dubbo錯(cuò)誤ip及ip亂入問(wèn)題的方法
今天小編就為大家分享一篇關(guān)于解決dubbo錯(cuò)誤ip及ip亂入問(wèn)題的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03

