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

微信开发者接入文档 : 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元每个月的隧道就行了,具体使用和配置参考:内网穿透常用的工具

5. 微信公众平台测试账号申请与功能权限列表

微信公众平台测试账号申请: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

接口功能权限列表:

三、整合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接口

我们需要在微信公众号后台配置访问这个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;
    }

}

4、服务器有效性校验Rest接口

在配置我们自己开发的后台管理系统对接入微信公众平台之前(也叫做接入开发者),我们来看一下需要哪些参数

 1. 需要的参数

 appId : 微信appId

 secret :   微信secret

 token :    微信token

 aesKey  微信加解密密钥(用到消息加解密需配置)

 需要将上述4个参数在微信平台填写好了之后,然后在我们自己的后台项目配置文件里配置好,接下来就是配置URL了,这个URL就是连接微信公众平台服务器跟我们自己的后台服务器的一根桥梁线,所以这里需要填写:http://xxxx.natapp1.cc/greenwx/wechat/portal   即可,也就是说这个URL是填写微信服务器将消息推送到我们服务器的一个地址,填写了我们服务的地址后,微信服务器就知道往这个URL所在的服务器推送消息,就可以产生交互。上面WxMpPortalController里面有两个方法,这两个方法是门户入口,是链接微信服务器的大门,你需要理解的是,默认的微信验签会走authGet这个方法,get请求,前面填写的4个参数就会在这个方法里走验签逻辑,验签不通过无法接入开发者模式; 另外一个接口的作用就是当用户在微信公众号内发送消息、发送图文、创建菜单等等时,微信服务器会把消息通过我们填写的这个URL地址推送到我们后台服务器,这个时候是走消息转发接口post, 请求方式是post,转发到post这个方法的接口上时,这个方法会根据消息类型判断,然后走路由转发,将请求转发到各个handler进行处理;

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

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

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

发布了329 篇原创文章 · 获赞 232 · 访问量 80万+

猜你喜欢

转载自blog.csdn.net/Thinkingcao/article/details/89332130