zoukankan      html  css  js  c++  java
  • 接入微信公众平台开发之用户关注(取消)事件触发后台自定义消息体通知给用户的实现过程

    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

  • 相关阅读:
    小波变换的引入,通俗易懂
    Leetcode 437. Path Sum III
    Leetcode 113. Path Sum II
    Leetcode 112 Path Sum
    Leetcode 520 Detect Capital
    Leetcode 443 String Compression
    Leetcode 38 Count and Say
    python中的生成器(generator)总结
    python的random模块及加权随机算法的python实现
    leetcode 24. Swap Nodes in Pairs(链表)
  • 原文地址:https://www.cnblogs.com/g177w/p/10053121.html
Copyright © 2011-2022 走看看