原创

Java开发微信公众号之整合weixin-java-tools框架开发微信公众号

版权声明: 本文为博主原创文章,转载请注明原文出处!
本文链接:https://thinkingcao.blog.csdn.net/article/details/89332130

微信开发者接入文档 : https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319

一、前言

在要做微信项目开发前,大家都会去了解微信公众号的类型和注册流程,以及不同公众号的功能使用权限,这个我前面文章也有过介绍,做微信开发公众号最起码得是一个已认证的服务号,关于微信公众号的类型和注册流程请参考这篇: Java微信公众号开发之初步认识微信公众平台 ,本次我主要记录下怎么将微信开源SDK的demo:https://github.com/binarywang/weixin-java-mp-demo-springmvc 接入到我们自己的项目中,因为里面有一套写的比较好的路由和微信接入入口,不用我们自己再去写,接下来关于写在前面的话,比较重要,请大家一定要认真阅读

二、写在前面的话

1、Spring+SpringMVC+Mybatis框架

 在整合微信框架weixin-java-tools之前,我假设你们已经使用Spring+SpringMVC+Mybatis技术栈搭建好了一套SSM框架

2、weixin-java-tools介绍

微信系列项目开发我们选用当下微信比较热门的框架WxJava,前名叫weixin-java-tools,WxJava (微信开发 Java SDK),涵盖了微信支付开放平台小程序企业微信/企业号公众号等的后端开发的SDK,该SDK封装了微信公众平台上大部分Api接口,我们开发时直接调用这个SDK里面的接口即可,同时作者针对WxJava 这个SDK还提供了一些接入的Demo,我们的主要目的就是引入WxJava 依赖和作者提供接入的demo,本次我们单纯的开发微信公众号项目,那么我们只需要weixin-java-tools中的微信公众号模块weixin-java-mp ,WxJava框架如下:

3、Maven 引用方式微信公众号SDK

  Maven引入微信公众号模块依赖如下:

  <!-- 微信框架 参考:https://github.com/Wechat-Group/weixin-java-tools -->
      <dependency>
         <groupId>com.github.binarywang</groupId>
         <artifactId>weixin-java-mp</artifactId>
         <version>3.0.0</version>
      </dependency>

4、内网穿透

关于微信开发,有个东西很重要,微信开发需要使用内网穿透才可以进行开发调试,也就是将本地localhost地址通过内网穿透,映射到外网去,通过外网才可以和微信的服务器进行消息通讯,数据的传输,这里我用过好几种内网穿透,为了避免大家不知道怎么选择,我推荐大家选择Natapp,Natapp很稳定,速度也快,https://natapp.cn/ ,单纯的微信开发调试选择购买9元每个月的隧道就行了,具体使用和配置参考:内网穿透常用的工具

三、整合weixin-java-mp-demo-springmvc

1、Demo项目

  1. 在码云和 GitHub 上均可访问,会尽量保持同步,请根据自己情况选用。
  2. 一般来说,Github上的版本应该是最新的,但也有可能没及时同步,此种情况下请以 Github 上的版本为准,有问题也请在 Github 对应项目 Issues 页面提问)。
  3. 欢迎提供更多的 demo 实现。

2、Spring Boot Starter 实现

3、Demo 列表

  1. 微信支付 Demo:GitHub码云
  2. 企业号/企业微信 Demo:GitHub码云
  3. 微信小程序 Demo:GitHub码云
  4. 开放平台 Demo:GitHub码云
  5. 公众号 Demo:
    • 使用 Spring MVC 实现的公众号 Demo:GitHub码云
    • 使用 Spring Boot 实现的公众号 Demo(支持多公众号):GitHub码云
    • 含公众号和部分微信支付代码的 Demo:GitHub码云

注: 如果你的项目是SpringBoot框架, 可以下载Demo列表中的SpringBoot版

 

 

4、下载weixin-java-demo-springmvc的demo

下载地址:  https://github.com/Wechat-Group/weixin-java-demo-springmvc     

5、微信路由WeixinService

demo下载下来后,看一下WeixinService代码,里面涉及到作者自己写的路由,如果不想自己写路由,可以直接借鉴复用

package com.github.binarywang.demo.spring.service;

import javax.annotation.PostConstruct;

import me.chanjar.weixin.mp.constant.WxMpEventConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.binarywang.demo.spring.config.WxMpConfig;
import com.github.binarywang.demo.spring.handler.AbstractHandler;
import com.github.binarywang.demo.spring.handler.KfSessionHandler;
import com.github.binarywang.demo.spring.handler.LocationHandler;
import com.github.binarywang.demo.spring.handler.LogHandler;
import com.github.binarywang.demo.spring.handler.MenuHandler;
import com.github.binarywang.demo.spring.handler.MsgHandler;
import com.github.binarywang.demo.spring.handler.NullHandler;
import com.github.binarywang.demo.spring.handler.StoreCheckNotifyHandler;
import com.github.binarywang.demo.spring.handler.SubscribeHandler;
import com.github.binarywang.demo.spring.handler.UnsubscribeHandler;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;

import static me.chanjar.weixin.common.api.WxConsts.*;

/**
 * 
 * @author Binary Wang
 *
 */
@Service
public class WeixinService extends WxMpServiceImpl {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected LogHandler logHandler;

    @Autowired
    protected NullHandler nullHandler;

    @Autowired
    protected KfSessionHandler kfSessionHandler;

    @Autowired
    protected StoreCheckNotifyHandler storeCheckNotifyHandler;

    @Autowired
    private WxMpConfig wxConfig;

    @Autowired
    private LocationHandler locationHandler;

    @Autowired
    private MenuHandler menuHandler;

    @Autowired
    private MsgHandler msgHandler;

    @Autowired
    private UnsubscribeHandler unsubscribeHandler;

    @Autowired
    private SubscribeHandler subscribeHandler;

    private WxMpMessageRouter router;

    @PostConstruct
    public void init() {
        final WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
        config.setAppId(this.wxConfig.getAppid());// 设置微信公众号的appid
        config.setSecret(this.wxConfig.getAppsecret());// 设置微信公众号的app corpSecret
        config.setToken(this.wxConfig.getToken());// 设置微信公众号的token
        config.setAesKey(this.wxConfig.getAesKey());// 设置消息加解密密钥
        super.setWxMpConfigStorage(config);

        this.refreshRouter();
    }

    private void refreshRouter() {
        final WxMpMessageRouter newRouter = new WxMpMessageRouter(this);

        // 记录所有事件的日志
        newRouter.rule().handler(this.logHandler).next();

        // 接收客服会话管理事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION).handler(this.kfSessionHandler).end();
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION).handler(this.kfSessionHandler).end();
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION).handler(this.kfSessionHandler).end();

        // 门店审核事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(WxMpEventConstants.POI_CHECK_NOTIFY).handler(this.storeCheckNotifyHandler).end();

        // 自定义菜单事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(MenuButtonType.CLICK).handler(this.getMenuHandler()).end();

        // 点击菜单连接事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(MenuButtonType.VIEW).handler(this.nullHandler).end();

        // 关注事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(EventType.SUBSCRIBE).handler(this.getSubscribeHandler()).end();

        // 取消关注事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(EventType.UNSUBSCRIBE).handler(this.getUnsubscribeHandler()).end();

        // 上报地理位置事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(EventType.LOCATION).handler(this.getLocationHandler()).end();

        // 接收地理位置消息
        newRouter.rule().async(false).msgType(XmlMsgType.LOCATION).handler(this.getLocationHandler()).end();

        // 扫码事件
        newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(EventType.SCAN).handler(this.getScanHandler()).end();

        // 默认
        newRouter.rule().async(false).handler(this.getMsgHandler()).end();

        this.router = newRouter;
    }

    public WxMpXmlOutMessage route(WxMpXmlMessage message) {
        try {
            return this.router.route(message);
        }
        catch (Exception e) {
            this.logger.error(e.getMessage(), e);
        }

        return null;
    }

    public boolean hasKefuOnline() {
        try {
            WxMpKfOnlineList kfOnlineList = this.getKefuService().kfOnlineList();
            return kfOnlineList != null && kfOnlineList.getKfOnlineList().size() > 0;
        }
        catch (Exception e) {
            this.logger.error("获取客服在线状态异常: " + e.getMessage(), e);
        }

        return false;
    }

    protected MenuHandler getMenuHandler() {
        return this.menuHandler;
    }

    protected SubscribeHandler getSubscribeHandler() {
        return this.subscribeHandler;
    }

    protected UnsubscribeHandler getUnsubscribeHandler() {
        return this.unsubscribeHandler;
    }

    protected AbstractHandler getLocationHandler() {
        return this.locationHandler;
    }

    protected MsgHandler getMsgHandler() {
        return this.msgHandler;
    }

    protected AbstractHandler getScanHandler() {
        return null;
    }

}

3、从这一步开始,我们就把上面的weixin-java-demo-springmvc demo代码接入到我们已经搭建好框架的项目中去

 1、 首先在我的项目中新建包名为wechat

  

2、然后将下载的Demo中包aop、builder、config、controller、dto、handler、service包括一个配置文件wx.properties复制到我们自己的项目中

移植到我们自己项目中的效果图如下,红框是移植过来的文件和配置:

 

3、这一步我们需要将上一步中移植过来的的wx.properties加载到Spring容器中,随着web.xml一起加载初始化,具体见下面截图红框框出来的,在我们自己项目中配置wx.properties如下:

  wx.properties内容展示:

#=========微信公众号开发基本配置============
#微信公众号的appid
wx_appid=xxx
#微信公众号的appsecret
wx_appsecret=xxx
#微信公众号的token
wx_token=xxx
#微信公众号的消息加解密密钥aeskey
wx_aeskey=WoDWc9c9jseK4gYzOcZChVaGDkcLTgmoS3O2F7KZtWV



   加载到Spring容器如下截图中红框所示

4、需要在wx.properties中配置微信公众平台的几个参数来接入微信服务器的验证参数 ,这里的=后面数值都要填上

#=========微信公众号开发基本配置============
#微信公众号的appid
wx_appid=xxx
#微信公众号的appsecret
wx_appsecret=xxx
#微信公众号的token
wx_token=xxx
#微信公众号的消息加解密密钥aeskey
wx_aeskey=WoDWc9c9jseK4gYzOcZChVaGDkcLTgmoS3O2F7KZtWV

5、微信的入口 :WxMpPortalController ,这里是跟微信公众平台配置我们项目服务器的URL交互类

package com.thinkgem.jeesite.modules.wechat.controller;

import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.thinkgem.jeesite.modules.wechat.service.WXLogService;
import com.thinkgem.jeesite.modules.wechat.service.WeixinService;

/**
 * 
 * @ClassName: WxMpPortalController
 * @Description: 微信主入口
 * @author CaoWenCao
 * @date 2018年6月12日 下午10:13:57
 */
@RestController
@RequestMapping("/wechat/portal")
public class WxMpPortalController {
    @Autowired
    private WeixinService wxService;
    @Autowired
    private WXLogService wXLogService;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /*
     * 微信验签
     */
    @ResponseBody
    @GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature, @RequestParam(name = "timestamp", required = false) String timestamp, @RequestParam(name = "nonce", required = false) String nonce,
            @RequestParam(name = "echostr", required = false) String echostr) {
        this.logger.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature, timestamp, nonce, echostr);

        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }

        if (this.getWxService().checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

    /*
     * 消息转发---中转站 每次微信端的消息都会来到这里进行分发 对微信公众号相关的一些动作,都以报文形式推送到该接口,根据请求的类型,进行路由分发处理
     */
    @ResponseBody
    @PostMapping(produces = "application/xml; charset=UTF-8")
    public String post(@RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam(name = "encrypt_type", required = false) String encType, @RequestParam(name = "msg_signature", required = false) String msgSignature,
            @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce) {
        this.logger.info("\n接收微信请求:[signature=[{}], encType=[{}], msgSignature=[{}]," + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", signature, encType, msgSignature, timestamp, nonce, requestBody);

        if (!this.wxService.checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
        }
             
        String out = null;
        if (encType == null) {
            // 明文传输的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
            // 如果是明文传输 ,保存 微信接收 信息,保存到数据库,用于微信消息管理中的客服互动
            wXLogService.doSaveReceiveLog(inMessage);
            //this.logger.info("\n保存微信接受信息WxMpXmlMessage:\n{}", inMessage);
            WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage);
            if (outMessage == null) {
                return "";
            }

            out = outMessage.toXml();
            // 日志出口时,保存微信发出去的XML(给用户)
            wXLogService.doSaveMsgLogOut(outMessage);
            //this.logger.info("\n保存微信输出日志WxMpXmlOutMessage信息:\n{}", outMessage);
           
        }
        else if ("aes".equals(encType)) {
            // aes加密的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, this.getWxService().getWxMpConfigStorage(), timestamp, nonce, msgSignature);
            this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString());
            // 如果是密文传输 ,保存 微信接收 信息
            wXLogService.doSaveReceiveLog(inMessage);
            WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage);
            if (outMessage == null) {
                return "";
            }
            out = outMessage.toEncryptedXml(this.getWxService().getWxMpConfigStorage());
            // 日志出口时,保存微信发出去的XML(给用户)
            wXLogService.doSaveMsgLogOut(outMessage);
            this.logger.info("\n保存微信输出日志WxMpXmlOutMessage信息:\n{}", outMessage);
            // 保存回复消息记录
            //wXLogService.doSaveReplyLog(outMessage);
        }

        this.logger.debug("\n组装回复信息:{}", out);

        return out;
    }

    protected WeixinService getWxService() {
        return this.wxService;
    }

}

6、整合完成后项目完整截图

 

 

四、对接微信公众平台

1、消息传递流程

关于微信公众号后台开发发出消息和收到响应结果的一个流程,大家看下面这张图

这是大家在公众号后台回复关键字的情况。那么这个消息是怎么样一个传递流程呢?我们来看看下面这张图:

这张图,我给大家稍微解释下:

首先"4" 这个字符从公众号上发送到了微信服务器
接下来微信服务器会把 “4” 转发到我自己的服务器上
我们服务器收到 “4” 这个字符之后,就去数据库中查询,将查询的结果,按照腾讯要求的 XML 格式进行返回
微信服务器把从我的服务器收到的信息,再发回到微信上,于是小伙伴们就看到了返回结果了
大致的流程就是这个样子。

接下来我们就来看一下实现细节。
 

2. 公众号后台配置

开发的第一步,是微信服务器要验证我们自己的服务器是否有效。

首先我们登录微信公众平台官网后,在公众平台官网的 开发-基本设置 页面,勾选协议成为开发者,然后点击“修改配置”按钮,填写:

  • 服务器地址(URL)
  • Token
  • EncodingAESKey

这里的 URL 配置好之后,我们需要针对这个 URL 开发两个接口,一个是 GET 请求的接口,这个接口用来做服务器有效性验证,另一个则是 POST 请求的接口,这个用来接收微信服务器发送来的消息。也就是说,微信服务器的消息都是通过 POST 请求发给我的。

Token 可由开发者可以任意填写,用作生成签名(该 Token 会和接口 URL 中包含的 Token 进行比对,从而验证安全性)。

EncodingAESKey 由开发者手动填写或随机生成,将用作消息体加解密密钥。

同时,开发者可选择消息加解密方式:明文模式、兼容模式和安全模式。明文模式就是我们自己的服务器收到微信服务器发来的消息是明文字符串,直接就可以读取并且解析,安全模式则是我们收到微信服务器发来的消息是加密的消息,需要我们手动解析后才能使用。
 

3、 服务器有效性校验

我们需要在微信公众号后台配置访问这个Rest接口

WxMpPortalController 微信消息交互接入门户入口
package com.thinkgem.jeesite.modules.wechat.controller;

import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.thinkgem.jeesite.modules.wechat.service.WXLogService;
import com.thinkgem.jeesite.modules.wechat.service.WeixinService;

/**
 * 
 * @ClassName: WxMpPortalController
 * @Description: 微信主入口
 * @author CaoWenCao
 * @date 2018年6月12日 下午10:13:57
 */
@RestController
@RequestMapping("/wechat/portal")
public class WxMpPortalController {
    @Autowired
    private WeixinService wxService;
    @Autowired
    private WXLogService wXLogService;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /*
     * 微信验签
     */
    @ResponseBody
    @GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature, @RequestParam(name = "timestamp", required = false) String timestamp, @RequestParam(name = "nonce", required = false) String nonce,
            @RequestParam(name = "echostr", required = false) String echostr) {
        this.logger.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature, timestamp, nonce, echostr);

        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }

        if (this.getWxService().checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

    /*
     * 消息转发---中转站 每次微信端的消息都会来到这里进行分发 对微信公众号相关的一些动作,都以报文形式推送到该接口,根据请求的类型,进行路由分发处理
     */
    @ResponseBody
    @PostMapping(produces = "application/xml; charset=UTF-8")
    public String post(@RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam(name = "encrypt_type", required = false) String encType, @RequestParam(name = "msg_signature", required = false) String msgSignature,
            @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce) {
        this.logger.info("\n接收微信请求:[signature=[{}], encType=[{}], msgSignature=[{}]," + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", signature, encType, msgSignature, timestamp, nonce, requestBody);

        if (!this.wxService.checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
        }
             
        String out = null;
        if (encType == null) {
            // 明文传输的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
            // 如果是明文传输 ,保存 微信接收 信息,保存到数据库,用于微信消息管理中的客服互动
            wXLogService.doSaveReceiveLog(inMessage);
            //this.logger.info("\n保存微信接受信息WxMpXmlMessage:\n{}", inMessage);
            WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage);
            if (outMessage == null) {
                return "";
            }

            out = outMessage.toXml();
            // 日志出口时,保存微信发出去的XML(给用户)
            wXLogService.doSaveMsgLogOut(outMessage);
            //this.logger.info("\n保存微信输出日志WxMpXmlOutMessage信息:\n{}", outMessage);
           
        }
        else if ("aes".equals(encType)) {
            // aes加密的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, this.getWxService().getWxMpConfigStorage(), timestamp, nonce, msgSignature);
            this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString());
            // 如果是密文传输 ,保存 微信接收 信息
            wXLogService.doSaveReceiveLog(inMessage);
            WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage);
            if (outMessage == null) {
                return "";
            }
            out = outMessage.toEncryptedXml(this.getWxService().getWxMpConfigStorage());
            // 日志出口时,保存微信发出去的XML(给用户)
            wXLogService.doSaveMsgLogOut(outMessage);
            this.logger.info("\n保存微信输出日志WxMpXmlOutMessage信息:\n{}", outMessage);
            // 保存回复消息记录
            //wXLogService.doSaveReplyLog(outMessage);
        }

        this.logger.debug("\n组装回复信息:{}", out);

        return out;
    }

    protected WeixinService getWxService() {
        return this.wxService;
    }

}

所以,微信服务器配置URL应该为:http://xxxx.natapp1.cc/greenwx/wechat/portal , 其中xxxx.natapp1.cc为内网穿透的域名

如果你的之前搭建的项目框架没有问题,这里就去开启开发者模式的服务器配置,开启成功后就正常集成weixin-java-mp框架了

 

到此为止,接入完成,可以开始调SDK接口开发微信相关功能,因为路由和服务器验证等等接口不用我们写了,这样我们只关注功能的实现就行了,框架的对接借鉴了demo,为开发时间节点省去了不少时间,如果对此文章有不懂流程的,请评论里留下问题,我会回复;

文章最后发布于: 2019-04-16 14:30:07
展开阅读全文
0 个人打赏
私信求帮助

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览