接入微信公眾平台開發之用戶關注(取消)事件觸發后台自定義消息體通知給用戶的實現過程


1.需求:用戶關注公眾號后回復給用戶一個字符串,字符串不能重復使用即如果a用戶關注公眾號后商戶后台回復給用戶字符串str1后,b用戶關注就是其他字符串,且a用戶取消關注再次關注不回復消息體

2.實現過程:

  ①首先配置服務器url並開啟,再次過程中需要微信后台與商戶后台進行通信,所以,微信后台會發送請求,商戶平台自定義接口回復相關內容即可完成通信。

    ②原理圖:

  ③代碼實現:

    a.pcodecontroller:定義的一個接口類,用來處理微信服務器發送的請求

  1 package com.java.zxf.controller;
  2 
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.io.OutputStream;
  6 import java.io.PrintWriter;
  7 import java.io.UnsupportedEncodingException;
  8 import java.util.HashMap;
  9 import java.util.List;
 10 import java.util.Map;
 11 import javax.servlet.ServletInputStream;
 12 import javax.servlet.ServletOutputStream;
 13 import javax.servlet.http.HttpServletRequest;
 14 import javax.servlet.http.HttpServletResponse;
 15 import org.apache.log4j.Logger;
 16 import org.dom4j.Document;
 17 import org.dom4j.Element;
 18 import org.dom4j.io.SAXReader;
 19 import org.springframework.beans.factory.annotation.Autowired;
 20 import org.springframework.stereotype.Controller;
 21 import org.springframework.web.bind.annotation.RequestMapping;
 22 import org.springframework.web.bind.annotation.ResponseBody;
 23 import weixin.popular.bean.xmlmessage.XMLMessage;
 24 import weixin.popular.bean.xmlmessage.XMLTextMessage;
 25 import weixin.popular.support.ExpireKey;
 26 import weixin.popular.support.expirekey.DefaultExpireKey;
 27 import com.easytouch.util.MyCheck;
 28 import com.java.zxf.dao.Pcodedao;
 29 import com.java.zxf.domain.pcode;
 30 
 31 @Controller
 32 public class PcodeController {
 33 
 34     @Autowired
 35     private Pcodedao pcodedao;
 36     private Logger log = Logger.getLogger(getClass());
 37     
 38     @RequestMapping("/getbyid")
 39     @ResponseBody
 40     public Map<String, Object> getbyid(HttpServletRequest request,int id){
 41         pcode code = pcodedao.getcodebyid(id);
 42         Map<String, Object> map = new HashMap<String, Object>();
 43         map.put("code", code);
 44         return map;
 45     }
 46     
 47     //重復通知過濾
 48     private static ExpireKey expireKey = new DefaultExpireKey();
 49 
 50 
 51     //微信推送事件 url
 52     @RequestMapping("/openwx/getticket")
 53     public void getTicket(HttpServletRequest request, HttpServletResponse response)
 54             throws Exception {
 55         ServletInputStream inputStream = request.getInputStream();
 56         ServletOutputStream outputStream = response.getOutputStream(); String signature = request.getParameter("signature");
 57         String timestamp = request.getParameter("timestamp");
 58         String nonce = request.getParameter("nonce");
 59         String echostr = request.getParameter("echostr");
 60 
 61         //首次請求申請驗證,返回echostr
 62         if(echostr!=null){
 63             outputStreamWrite(outputStream,echostr);
 64             return;
 65         }
 66 
 67         //驗證請求簽名
 68         if(!MyCheck.checkSignature(signature, timestamp, nonce)){
 69             System.out.println("The request signature is invalid");
 70             return;
 71         }
 72 
 73         boolean isreturn= false;
 74         //loger.info("1.收到微信服務器消息");
 75         Map<String, String> wxdata=parseXml(request);
 76         if(wxdata.get("MsgType")!=null){
 77             if("event".equals(wxdata.get("MsgType"))){
 78                 //loger.info("2.1解析消息內容為:事件推送");
 79                 if( "subscribe".equals(wxdata.get("Event"))){
 80                     //loger.info("2.2用戶第一次關注 返回true哦");
 81                     isreturn=true;
 82                 }
 83             }
 84         }
 85 
 86         if(isreturn == true){
 87             String openid = wxdata.get("FromUserName");
 88             String tosend = "抱歉,提貨碼已用完";
 89             String key = wxdata.get("FromUserName")+ "__"
 90                     + wxdata.get("ToUserName")+ "__"
 91                     + wxdata.get("MsgId") + "__"
 92                     + wxdata.get("CreateTime");
 93             if(expireKey.exists(key)){
 94                 //重復通知不作處理
 95                 //loger.info("3.1  重復通知了");
 96                 return;
 97             }else{
 98                 //loger.info("3.1  第一次通知");
 99                  //轉換XML
100                 //loger.info("3.0 進入回復 轉換對象:"+key);
101                 pcode temp = pcodedao.getbyopenid(openid);
102                 if (temp==null){
103                     List<pcode> pcodelist = pcodedao.getAllcode();
104                     try{
105                         pcode code = pcodelist.get(0);
106                         tosend = "您的提貨碼為:"+code.getPickupcode();
107                         int flag = pcodedao.update(code.getId(),openid);
108                         if(flag==1){
109                             System.out.println("更新成功,取貨碼已使用");
110                         }else{
111                             log.error("更新用戶openid失敗,取貨碼未能使用");
112                         }
113                     }catch(Exception e){
114                         System.out.println("取貨碼已經用完");
115                         log.info("取貨碼已經用完");
116                     }
117                   //loger.info("3.2  回復你好");
118                     //創建回復
119                     XMLMessage xmlTextMessage = new XMLTextMessage(
120                             wxdata.get("FromUserName"),
121                             wxdata.get("ToUserName"),
122                             tosend);
123                     expireKey.add(key);
124                     //回復
125                     xmlTextMessage.outputStreamWrite(outputStream);
126                     return;
127                 }
128                 }
129         }
130         //loger.info("3.2  回復空");
131         outputStreamWrite(outputStream,"");
132     }
133 
134     /**
135      * 數據流輸出
136      * @param outputStream
137      * @param text
138      * @return
139      */
140     private boolean outputStreamWrite(OutputStream outputStream, String text){
141         try {
142             outputStream.write(text.getBytes("utf-8"));
143         } catch (UnsupportedEncodingException e) {
144             // TODO Auto-generated catch block
145             e.printStackTrace();
146             return false;
147         } catch (IOException e) {
148             // TODO Auto-generated catch block
149             e.printStackTrace();
150             return false;
151         }
152         return true;
153     }
154 
155     /**
156      * dom4j 解析 xml 轉換為 map
157      * @param request
158      * @return
159      * @throws Exception
160      */
161     public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
162         // 將解析結果存儲在HashMap中
163         Map<String, String> map = new HashMap<String, String>();
164         // 從request中取得輸入流
165         InputStream inputStream = request.getInputStream();
166         // 讀取輸入流
167         SAXReader reader = new SAXReader();
168         Document document = reader.read(inputStream);
169         // 得到xml根元素
170         Element root = document.getRootElement();
171         // 得到根元素的所有子節點
172         List<Element> elementList = root.elements();
173 
174         // 遍歷所有子節點
175         for (Element e : elementList)
176             map.put(e.getName(), e.getText());
177 
178         // 釋放資源
179         inputStream.close();
180         inputStream = null;
181         return map;
182     }
183 
184     /**
185      * 回復微信服務器"文本消息"
186      * @param response
187      * @param returnvaleue
188      */
189     public void output(HttpServletResponse response, String returnvaleue) {
190         try {
191             PrintWriter pw = response.getWriter();
192             pw.write(returnvaleue);
193             pw.flush();
194         } catch (IOException e) {
195             e.printStackTrace();
196         }
197     }
198 }
View Code

    b.pcodedao:商戶后台應用-數據層;定義的讀寫數據的類

 1 package com.java.zxf.dao;
 2 
 3 import java.util.List;
 4 import org.apache.ibatis.annotations.Param;
 5 import org.apache.ibatis.annotations.Select;
 6 import org.apache.ibatis.annotations.Update;
 7 import org.springframework.stereotype.Repository;
 8 
 9 import com.java.zxf.domain.pcode;
10 @Repository
11 public interface Pcodedao {
12     @Select("select * from pcode where id=#{id}")
13     public pcode getcodebyid(int id);
14     
15     @Select("select * from pcode where openid is null or openid=''")
16     public List<pcode> getAllcode();
17     
18     @Select("select * from pcode where openid=#{openid}")
19     public pcode getbyopenid(String openid);
20     
21     @Update("update pcode set openid=#{openid} where id=#{id}")
22     public int update(@Param(value="id")int id,@Param(value="openid")String openid);
23 }
View Code

    c.pom.xml中添加的依賴包

		<dependency>
		    <groupId>dom4j</groupId>
		    <artifactId>dom4j</artifactId>
		    <version>1.6.1</version>
		</dependency>
		<dependency>
		  <groupId>com.github.liyiorg</groupId>
		  <artifactId>weixin-popular</artifactId>
		  <version>2.8.24</version>
		</dependency>

  三.總結:微信公眾平台提供了包括關注動作,被動回復消息在內的一系列動作,具體見如下鏈接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM