溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

微信開發(fā)之如何處理微信客戶端發(fā)來的消息

發(fā)布時(shí)間:2021-09-10 11:46:52 來源:億速云 閱讀:236 作者:小新 欄目:移動(dòng)開發(fā)

這篇文章主要介紹微信開發(fā)之如何處理微信客戶端發(fā)來的消息,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

在開啟微信開發(fā)者模式時(shí),我們配置了一個(gè)URL地址,當(dāng)我們提交開啟微信開發(fā)者模式,騰訊的微信服務(wù)器會(huì)向該URL地址發(fā)送一個(gè)get請(qǐng)求,并且攜帶一些參數(shù),讓我們來驗(yàn)證。說到get請(qǐng)求,就必須說到post請(qǐng)求,關(guān)注我們公眾號(hào)的微信粉絲發(fā)來的消息,觸發(fā)的事件,騰訊的微信服務(wù)器則會(huì)像該URL地址發(fā)送一個(gè)post請(qǐng)求,請(qǐng)求的內(nèi)容就是以xml文檔形式的字符串。

所以該URL地址的get請(qǐng)求的處理方法,專門用于開啟微信開發(fā)者模式;而post請(qǐng)求則用于處理微信粉絲發(fā)給我們的消息,或者觸發(fā)的事件,所以我們后面的微信開發(fā)工作的起點(diǎn)就是該URL地址的post處理方法。

下面我們處理一個(gè)最簡(jiǎn)單的例子:粉絲發(fā)送任意一個(gè)文本信息給我們,我們給他回復(fù)一個(gè)消息:“你好,+ 他微信的openId”

下面直接貼代碼:

URL對(duì)應(yīng)的處理servlet:

public class CoreServlet extends HttpServlet 
{
	private static final long serialVersionUID = 4440739483644821986L;

	/**
	 * 請(qǐng)求校驗(yàn)(確認(rèn)請(qǐng)求來自微信服務(wù)器)
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		// 微信服務(wù)端發(fā)來的加密簽名
		String signature = request.getParameter("signature");
		// 時(shí)間戳
		String timestamp = request.getParameter("timestamp");
		// 隨機(jī)數(shù)
		String nonce = request.getParameter("nonce");
		// 隨機(jī)字符串
		String echostr = request.getParameter("echostr");
		
		PrintWriter out = response.getWriter();
		// 請(qǐng)求校驗(yàn),若校驗(yàn)成功則原樣返回echostr,表示接入成功,否則接入失敗
		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
			out.print(echostr);
		}
		out.close();
		out = null;
	}

	/**
	 * 請(qǐng)求校驗(yàn)與處理
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		// 將請(qǐng)求、響應(yīng)的編碼均設(shè)置為UTF-8(防止中文亂碼)
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		// 接收參數(shù)微信加密簽名、 時(shí)間戳、隨機(jī)數(shù)
		String signature = request.getParameter("signature");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");

		PrintWriter out = response.getWriter();
		// 請(qǐng)求校驗(yàn)
		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
			Message msgObj = XMLUtil.getMessageObject(request);	// 讀取微信客戶端發(fā)來的消息(xml字符串),并將其轉(zhuǎn)換為消息對(duì)象
			if(msgObj != null){
				String xml = "<xml>" +
						 "<ToUserName><![CDATA[" + msgObj.getFromUserName() + "]]></ToUserName>" +	// 接收方帳號(hào)(收到的OpenID)
						 "<FromUserName><![CDATA[" + msgObj.getToUserName() + "]]></FromUserName>" +	// 開發(fā)者微信號(hào)
						 "<CreateTime>12345678</CreateTime>" +
						 "<MsgType><![CDATA[text]]></MsgType>" +
						 "<Content><![CDATA[你好,"+ msgObj.getFromUserName() +"]]></Content>" +
						 "</xml>";
				out.write(xml);	// 回復(fù)微信客戶端的消息(xml字符串)
				out.close();
				return;
			}
		}
		out.write("");
		out.close();
	}
}

xml字符串的處理工具類,實(shí)現(xiàn)xml消息到消息對(duì)象的轉(zhuǎn)換:

public class XMLUtil 
{
	/**
	 * 從request中讀取用戶發(fā)給公眾號(hào)的消息內(nèi)容
	 * @param request
	 * @return 用戶發(fā)給公眾號(hào)的消息內(nèi)容
	 * @throws IOException
	 */
	public static String readRequestContent(HttpServletRequest request) throws IOException
	{
		// 從輸入流讀取返回內(nèi)容
		InputStream inputStream = request.getInputStream();
		InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
		String str = null;
		StringBuilder buffer = new StringBuilder();
		
		while ((str = bufferedReader.readLine()) != null) {
			buffer.append(str);
		}
		
		// 釋放資源
		bufferedReader.close();
		inputStreamReader.close();
		inputStream.close();
		
		return buffer.toString();
	}
	
	/**
	 * 將xml文檔的內(nèi)容轉(zhuǎn)換成map
	 * @param xmlDoc
	 * @return map
	 */
	public static Map<String, String> xmlToMap(String xmlDoc)
	{
		//創(chuàng)建一個(gè)新的字符串
        StringReader read = new StringReader(xmlDoc);
        //創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對(duì)象來確定如何讀取 XML 輸入
        InputSource source = new InputSource(read);
        //創(chuàng)建一個(gè)新的SAXBuilder
        SAXBuilder sb = new SAXBuilder();
        
        Map<String, String> xmlMap = new HashMap<String, String>();
        try {
            Document doc = sb.build(source);	//通過輸入源構(gòu)造一個(gè)Document
            Element root = doc.getRootElement();	//取的根元素
            
            List<Element> cNodes = root.getChildren();	//得到根元素所有子元素的集合(根元素的子節(jié)點(diǎn),不包括孫子節(jié)點(diǎn))
            Element et = null;
            for(int i=0;i<cNodes.size();i++){
                et = (Element) cNodes.get(i);	//循環(huán)依次得到子元素
                xmlMap.put(et.getName(), et.getText());
            }
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return xmlMap;
	}
	
	/**
	 * 將保存xml內(nèi)容的map轉(zhuǎn)換成對(duì)象
	 * @param map
	 * @return
	 */
	public static Message getMessageObject(Map<String, String> map)
	{
		if(map != null){
			String MsgType = map.get("MsgType");
			
			// 消息類型(文本消息:text, 圖片消息:image, 語音消息:voice, 視頻消息:video, 
			// 地理位置消息:location, 鏈接消息:link)
			if("text".equals(MsgType)){
				TextMessage msg = new TextMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setContent(map.get("Content"));
				return msg;
			}
			if("ImageMessage".equals(MsgType)){
				ImageMessage msg = new ImageMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setPicUrl(map.get("PicUrl"));
				msg.setMediaId(map.get("MediaId"));
				return msg;
			}
			if("video".equals(MsgType)){
				VideoMessage msg = new VideoMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setMediaId(map.get("MediaId"));
				msg.setThumbMediaId(map.get("ThumbMediaId"));
				return msg;
			}
			if("voice".equals(MsgType)){
				VoiceMessage msg = new VoiceMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setMediaId(map.get("MediaId"));
				msg.setFormat(map.get("Format"));
				return msg;
			}
			if("location".equals(MsgType)){
				LocationMessage msg = new LocationMessage();

				msg.setLocation_X(map.get("Location_X"));
				msg.setLocation_Y(map.get("Location_Y"));
				msg.setScale(map.get("Scale"));
				msg.setLabel(map.get("Label"));
				return msg;
			}
			if("link".equals(MsgType)){
				LinkMessage msg = new LinkMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setTitle(map.get("Title"));
				msg.setDescription(map.get("Description"));
				msg.setUrl(map.get("Url"));
				return msg;
			}
		}
		return null;
	}
	
	/**
	 * 將保存xml內(nèi)容的map轉(zhuǎn)換成對(duì)象
	 * @param map
	 * @return
	 * @throws IOException 
	 */
	public static Message getMessageObject(HttpServletRequest request) throws IOException
	{
		String xmlDoc = XMLUtil.readRequestContent(request);	// 讀取微信客戶端發(fā)了的消息(xml)
		Map<String, String> map = XMLUtil.xmlToMap(xmlDoc);		// 將客戶端發(fā)來的xml轉(zhuǎn)換成Map
		if(map != null){
			String MsgType = map.get("MsgType");
			
			// 消息類型(文本消息:text, 圖片消息:image, 語音消息:voice, 視頻消息:video, 
			// 地理位置消息:location, 鏈接消息:link)
			if("text".equals(MsgType)){
				TextMessage msg = new TextMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setContent(map.get("Content"));
				return msg;
			}
			/*if("ImageMessage".equals(MsgType)){
				ImageMessage msg = new ImageMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setPicUrl(map.get("PicUrl"));
				msg.setMediaId(map.get("MediaId"));
				return msg;
			}
			if("video".equals(MsgType)){
				VideoMessage msg = new VideoMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setMediaId(map.get("MediaId"));
				msg.setThumbMediaId(map.get("ThumbMediaId"));
				return msg;
			}
			if("voice".equals(MsgType)){
				VoiceMessage msg = new VoiceMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setMediaId(map.get("MediaId"));
				msg.setFormat(map.get("Format"));
				return msg;
			}
			if("location".equals(MsgType)){
				LocationMessage msg = new LocationMessage();

				msg.setLocation_X(map.get("Location_X"));
				msg.setLocation_Y(map.get("Location_Y"));
				msg.setScale(map.get("Scale"));
				msg.setLabel(map.get("Label"));
				return msg;
			}
			if("link".equals(MsgType)){
				LinkMessage msg = new LinkMessage();
				XMLUtil.initCommonMsg(msg, map);
				
				msg.setTitle(map.get("Title"));
				msg.setDescription(map.get("Description"));
				msg.setUrl(map.get("Url"));
				return msg;
			}*/
		}
		return null;
	}
	
	public static void initCommonMsg(Message msg, Map<String, String> map)
	{
		msg.setMsgId(map.get("MsgId"));
		msg.setMsgType(map.get("MsgType"));
		msg.setToUserName(map.get("ToUserName"));
		msg.setFromUserName(map.get("FromUserName"));
		msg.setCreateTime(map.get("CreateTime"));
	}
}

粉絲發(fā)來的消息分為了6中類型(文本消息, 圖片消息, 語音消息, 視頻消息, 地理位置消息, 鏈接消息):

/**
 * 微信消息基類
 * @author yuanfang
 * @date 2015-03-23
 */
public class Message 
{
	private String MsgId;	// 消息id,64位整型
	private String MsgType;	// 消息類型(文本消息:text, 圖片消息:image, 語音消息:voice, 視頻消息:video, 地理位置消息:location, 鏈接消息:link)
	private String ToUserName;	//開發(fā)者微信號(hào)
	private String FromUserName; // 發(fā)送方帳號(hào)(一個(gè)OpenID)
	private String CreateTime;	// 消息創(chuàng)建時(shí)間 (整型)
	
	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 String getCreateTime() {
		return CreateTime;
	}
	public void setCreateTime(String createTime) {
		CreateTime = createTime;
	}
	public String getMsgType() {
		return MsgType;
	}
	public void setMsgType(String msgType) {
		MsgType = msgType;
	}
	public String getMsgId() {
		return MsgId;
	}
	public void setMsgId(String msgId) {
		MsgId = msgId;
	}
	
}

文本消息類:

package com.sinaapp.wx.msg;

public class TextMessage extends Message 
{
	private String Content;	// 文本消息內(nèi)容

	public String getContent() {
		return Content;
	}

	public void setContent(String content) {
		Content = content;
	}
	
}

以上是“微信開發(fā)之如何處理微信客戶端發(fā)來的消息”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI