• 1.0 开发背景 外包公司,所以各种各样的项目都有接触,有个需求,客户要... 注意 :在微信公众号后台,设置了服务器配置 URL 并启用后,会导致 微信后台设置的回复规则,以及底部菜单都全部失效!直接清空了!因为...
    **1.0 开发背景**
    		外包公司,所以各种各样的项目都有接触,有个需求,客户要做不同的二维码,通过二维码关注以后,给用户发送不同的消息,顺便统计用户来源,
    		本文用到了  微信带参数二维码接口和消息管理里的相关接口
    		**注意 :在微信公众号后台,设置了服务器配置  URL  并启用后,会导致 微信后台设置的回复规则,以及底部菜单都全部失效!直接清空了!因为这时候 微信已经把公众号消息和事件 推送给开发者配置的url中,让开发者进行处理了。**
    		本文先讲述微信官方后台设置带参二维码,后续更新使用第三方平台开发实现这个功能,从而保证了用户微信公众号官方设置底部菜单以及自定义回复没有失效!
    
    **2.0 开发准备**
    		2.1老样子 官方文档 来一波 [带参二维码](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542) [接收事件](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454)
    		2.2 需要在微信后台 配置服务器配置  ,微信会在你修改这个配置的时候 给你填写的URL发送数据,需要提前把项目上传服务器!
    			![这里写图片描述](https://img-blog.csdn.net/20171022205422735?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ2hlbk1Nbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
    
    这个东西 配置好之后 可以点击开启了 ,开启后啊,这个微信会把所有用户发送的信息,给转发给填写的url 上。开发者必须在五秒内回复微信服务器。否则 微信会进行三次重试,重试均失败后,会给用户提示 该公众号暂时无法提供服务。 而且在公众平台还有告警通知。
    
       下面看代码
       
    
    ```
    package com.ysh.wxtest.controller;
    
    import org.apache.log4j.Logger;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import weixin.popular.bean.xmlmessage.XMLMessage;
    import weixin.popular.bean.xmlmessage.XMLTextMessage;
    import weixin.popular.support.ExpireKey;
    import weixin.popular.support.expirekey.DefaultExpireKey;
    import weixin.popular.util.SignatureUtil;
    
    import javax.servlet.ServletInputStream;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 消息接收控制层
     * @author YaoShiHang
     * @Date 15:15 2017-10-16
     */
    @Controller
    public class WxqrcodeController {
    
        private final String TOKEN="xxxxxxxxxx";                      //Wx 开发者设置的 token
        private Logger loger = Logger.getLogger(getClass());
        //重复通知过滤
        private static ExpireKey expireKey = new DefaultExpireKey();
    
    
        //微信推送事件 url
        @RequestMapping("/openwx/getticket")
        public void getTicket(HttpServletRequest request, HttpServletResponse response)
                throws Exception {
            ServletInputStream inputStream = request.getInputStream();
            ServletOutputStream outputStream = response.getOutputStream(); String signature = request.getParameter("signature");
            String timestamp = request.getParameter("timestamp");
            String nonce = request.getParameter("nonce");
            String echostr = request.getParameter("echostr");
    
            //首次请求申请验证,返回echostr
            if(echostr!=null){
                outputStreamWrite(outputStream,echostr);
                return;
            }
    
            //验证请求签名
            if(!signature.equals(SignatureUtil.generateEventMessageSignature(TOKEN,timestamp,nonce))){
                System.out.println("The request signature is invalid");
                return;
            }
    
            boolean isreturn= false;
            loger.info("1.收到微信服务器消息");
            Map wxdata=parseXml(request);
            if(wxdata.get("MsgType")!=null){
                if("event".equals(wxdata.get("MsgType"))){
                    loger.info("2.1解析消息内容为:事件推送");
                    if( "subscribe".equals(wxdata.get("Event"))){
                        loger.info("2.2用户第一次关注 返回true哦");
                        isreturn=true;
                    }
                }
            }
    
            if(isreturn == true){
                //转换XML
                String key = wxdata.get("FromUserName")+ "__"
                        + wxdata.get("ToUserName")+ "__"
                        + wxdata.get("MsgId") + "__"
                        + wxdata.get("CreateTime");
                loger.info("3.0 进入回复 转换对象:"+key);
    
                if(expireKey.exists(key)){
                    //重复通知不作处理
                    loger.info("3.1  重复通知了");
                    return;
                }else{
                    loger.info("3.1  第一次通知");
                    expireKey.add(key);
                }
    
                loger.info("3.2  回复你好");
                //创建回复
                XMLMessage xmlTextMessage = new XMLTextMessage(
                        wxdata.get("FromUserName"),
                        wxdata.get("ToUserName"),
                        "你好");
                //回复
                xmlTextMessage.outputStreamWrite(outputStream);
                return;
            }
            loger.info("3.2  回复空");
            outputStreamWrite(outputStream,"");
        }
    
        /**
         * 数据流输出
         * @param outputStream
         * @param text
         * @return
         */
        private boolean outputStreamWrite(OutputStream outputStream, String text){
            try {
                outputStream.write(text.getBytes("utf-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * dom4j 解析 xml 转换为 map
         * @param request
         * @return
         * @throws Exception
         */
        public static Map parseXml(HttpServletRequest request) throws Exception {
            // 将解析结果存储在HashMap中
            Map map = new HashMap();
            // 从request中取得输入流
            InputStream inputStream = request.getInputStream();
            // 读取输入流
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            // 得到xml根元素
            Element root = document.getRootElement();
            // 得到根元素的所有子节点
            List elementList = root.elements();
    
            // 遍历所有子节点
            for (Element e : elementList)
                map.put(e.getName(), e.getText());
    
            // 释放资源
            inputStream.close();
            inputStream = null;
            return map;
        }
    
        /**
         * 回复微信服务器"文本消息"
         * @param response
         * @param returnvaleue
         */
        public void output(HttpServletResponse response, String returnvaleue) {
            try {
                PrintWriter pw = response.getWriter();
                pw.write(returnvaleue);
                loger.info("****************return valeue***************="+returnvaleue);
                pw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    ```
    
    提供一个大神的帮助类
    
    ```
    package weixin.popular.bean.xmlmessage;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.util.UUID;
    
    import com.qq.weixin.mp.aes.AesException;
    import com.qq.weixin.mp.aes.WXBizMsgCrypt;
    
    import weixin.popular.bean.message.message.Message;
    
    public abstract class XMLMessage {
    
    	protected String toUserName;
    	protected String fromUserName;
    	protected String msgType;
    
    	protected XMLMessage(String toUserName, String fromUserName, String msgType) {
    		super();
    		this.toUserName = toUserName;
    		this.fromUserName = fromUserName;
    		this.msgType = msgType;
    	}
    
    	/**
    	 * 子类自定义XML
    	 * @return XML
    	 */
    	public abstract String subXML();
    	
    	/**
    	 * 转换为  Message 对象
    	 * @return Message
    	 */
    	public abstract Message convert();
    
    	public String toXML(){
    		StringBuilder sb = new StringBuilder();
    		sb.append("");
    		sb.append("");
    		sb.append("");
    		sb.append(""+System.currentTimeMillis()/1000+"");
    		sb.append("");
    		sb.append(subXML());
    		sb.append("");
    		return sb.toString();
    	}
    
    	public boolean outputStreamWrite(OutputStream outputStream){
    		try {
    			outputStream.write(toXML().getBytes("utf-8"));
    			outputStream.flush();
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    			return false;
    		} catch (IOException e) {
    			e.printStackTrace();
    			return false;
    		}
    		return true;
    	}
    
    	public boolean outputStreamWrite(OutputStream outputStream,WXBizMsgCrypt bizMsgCrypt){
    		if(bizMsgCrypt != null){
    			try {
    				String outputStr = bizMsgCrypt.encryptMsg(toXML(), System.currentTimeMillis()+"",UUID.randomUUID().toString());
    				outputStream.write(outputStr.getBytes("utf-8"));
    				outputStream.flush();
    			} catch (UnsupportedEncodingException e) {
    				e.printStackTrace();
    				return false;
    			} catch (IOException e) {
    				e.printStackTrace();
    				return false;
    			} catch (AesException e) {
    				e.printStackTrace();
    				return false;
    			}
    			return true;
    		}else{
    			return outputStreamWrite(outputStream);
    		}
    	}
    
    	public String getToUserName() {
    		return toUserName;
    	}
    
    	public String getFromUserName() {
    		return fromUserName;
    	}
    
    	public String getMsgType() {
    		return msgType;
    	}
    	
    	
    }
    
    ```
    
    
    展开全文
  • 想自己开一个公众号,先学习一下用 Java 进行微信公众号开发微信公众号的管理有开发模式和编辑模式两种,两者是互斥的。 腾讯是这么讲的: 编辑模式:编辑模式指所有的公众号运营者都可以通过简单的编辑...
  • 接收普通消息主要包括:文本消息、图片消息、语音消息、视频消息、小视频消息、地理位置消息、链接消息。XML数据包结构和相关参数如下: 1、文本消息 1348831860 1234567890123456 参数
  • 微信获取公众号文章就是指在第三方平台获取公众号作者写的文章。 一. 第三方开发需要到微信开放平台注册并且创建一个第三方平台应用 创建第三方平台时要填写很多资料,其中填写的回调地址需要记下来,等下要用到 ....
  • 微信公众平台开发入门 2019-12-30 15:18:17
    通过本课程的学习,学员能够入门微信公众平台开发,能够胜任企业级的订阅号、服务号、企业号的应用开发工作。 通过本课程的学习,学员能够对微信公众平台有一个清晰的、系统性的认识。例如,公众号是什么,它有...
  • 当普通微信用户向公众号发送消息或者与微信公众号进行互动触发某些事件时,微信服务器将会把这些消息或者事件以XML数据包格式POST到开发者配置的服务器地址URL上
  • 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。 现在,我们要实现一个微信内网页,通过微信访问网页时,网页会展示微信用户的个人信息。因为涉及...
  • 微信公众号主要有以下几个步骤 微信公众号的通讯机制 微信公众号简介 1.注册微信公众号 2.注册测试公众号 3.搭建微信本地调试环境 1)下载客户端natapp: 2)安装natapp: 4.微信公众号接入(校验签名) 第1步中...
  • 基于python的微信公众号开发教程
  • 微信公众平台开发公众号JSSDK开发是子恒老师《微信公众平台开发》视频教程的第9部。详细讲解了用php开发微信公众号,对微信公众平台中的JSSDK开发。内容包含用JSSDK获取网络状态,地理位置,分享到朋友圈,QQ,...
  • 服务器端采用springBoot开发微信公众号功能,实现与用户的交互,返回用户输入的内容
  • 为啥要获取公众号的access_token? 因为接下来要实现微信公众号的自定义菜单需要access_token,而且菜单的URl跳转第三方网页也要用到。 一、access_token简介 为了使第三方开发者能够为用户提供更多更有价值的...
  • 微信公众平台开发微信用户开发管理是子恒老师《微信公众平台开发》视频教程的第7部。详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户...
  • 微信公众号开发基本流程 2019-04-26 09:40:21
    过年前后做了个微信公众号项目,已经过去一段时间了,抽空回忆总结下基本流程吧,不然很快估计自己就忘了。。 微信公众平台官网:https://mp.weixin.qq.com 文章目录一、注册公众号二、了解公众号管理页面三、必备...
  • 在我们做微信公众号开发时,发送模板消息往往是必不可少的功能。今天我们就来说说吧! 1、申请模板消息 首先我们应该知道,模板消息是需要申请的。这个申请就其本身来说是很easy的(我前一天晚上申请的,显示需要2...
  • 微信公众号之开发者工具 2020-04-06 16:49:32
    这次的项目主要是关于微信公众号的一个开发,本人这次分配的模块是后台微信公众号的支付和退款,第一次接触微信公众的项目刚开始一脸懵逼,开发过程中遇到各种坑,所以想自己写一篇详细的关于微信公众号开发,希望...
  • 微信公众号主要面向名人、政府、媒体、企业等机构推出的合作推广业务。在这里可以通过微信渠道将品牌推广给上亿的微信用户,减少宣传成本,提高品牌知名度,打造更具影响力的品牌形象。 3. 公众平台 微信公众平...
  • 说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! ... 一丶概论 公众号接收与发送消息 ...如果公众号类型为服务号(订阅号只能使用普通消息接口),可以在公众平台网站中申请认证...
  • 微信公众号开发详细教程 2019-05-24 17:53:17
    微信公众号开发之配置开发服务器 微信公众号开发获取access_token 微信公众号开发之关键词回复 微信公众号开发之模板消息 微信公众号开发之授权回调 ...
  • vue开发微信公众号入门系列 最近需要开发微信公众号,前端使用的vue框架,看完腾讯的,我的内心无比沉重,天噜啦,生无可恋~~~ 简单的总结一下吧, 1页面绘制 微信公众号开发而言还是使用基础的html、css、js绘制...
1 2 3 4 5 ... 20
收藏数 58,075
精华内容 23,230