个人只能申请订阅号

1、首先需要申请一个微信公众号。具体如何申请,请登录微信公众号平台申请即可

2、外网映射工具——ngrok

项目使用spring boot 开发  结合自己项目 引入如下依赖及三个java文件

     <!-- 微信开发工具包 -->
        <!-- https://github.com/binarywang/weixin-java-mp-demo-springboot -->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-mp</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.0.7</version>
        </dependency>
WeChatProperties.java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "wechat.config")
public class WeChatProperties {

    /**
     * 是否使用redis存储access token
     */
    private boolean useRedis;

    /**
     * 设置微信公众号的appid
     */
    private String appId;

    /**
     * 设置微信公众号的app secret
     */
    private String appSecret;

    /**
     * 设置微信公众号的token
     */
    private String token;

    /**
     * 设置微信公众号的EncodingAESKey
     */
    private String aesKey;

    private String mpVerify;

    private String jobTemplateId1;

}

WeChatConfig.java
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.redis.JedisWxRedisOps;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WeChatProperties.class)
public class WeChatConfig {
    @Autowired
    WeChatProperties weChatProperties;
    @Autowired
    RedisProperties redisProperties;

    @Bean
    public WxMpService wxMpService() {
        if (StringUtils.isAnyBlank(weChatProperties.getAppId(), weChatProperties.getAppSecret(), weChatProperties.getAesKey(), weChatProperties.getToken())) {
            throw new RuntimeException("请检查微信公众平台开发配置文件");
        }

        /**
         * WxMpServiceImpl继承WxMpServiceHttpClientImpl 内部获取了AccessToken
         */
        WxMpServiceImpl wxMpService = new WxMpServiceImpl();
        WxMpConfigStorage wxMpConfigStorage = wxMpConfigStorage(weChatProperties.isUseRedis());
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage);
        return wxMpService;
    }


    public WxMpConfigStorage wxMpConfigStorage(Boolean isUseRedis) {
        WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();

        if (weChatProperties.isUseRedis()) {
            String host = redisProperties.getHost();
            Integer port = redisProperties.getPort();
            if (StringUtils.isAnyBlank(host, port.toString())) {
                throw new RuntimeException("请检查配置文件中redis====> host,port 不能为空");
            }
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            JedisPool jedisPool = new JedisPool(poolConfig, host, port);
            configStorage = new WxMpRedisConfigImpl(new JedisWxRedisOps(jedisPool), weChatProperties.getAppId());
        }

        configStorage.setAppId(weChatProperties.getAppId());
        configStorage.setSecret(weChatProperties.getAppSecret());
        configStorage.setAesKey(weChatProperties.getAesKey());
        configStorage.setToken(weChatProperties.getToken());
        //String accessToken = AccessTokenUtils.getToken(weChatProperties.getAppId(),weChatProperties.getAppSecret());
        //configStorage.setAccessToken(accessToken);
        return configStorage;
    }

    @Bean
    public WxMpXmlMessage wxMpXmlMessage() {
        return new WxMpXmlMessage();
    }


}
WxController.java
package com.frkj.modules.wechat;

import cn.hutool.json.JSONObject;

import com.frkj.common.api.vo.Result;
import com.frkj.common.exception.WechatException;
import com.frkj.common.util.MessageUtils;
import com.frkj.config.WeChatProperties;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.menu.WxMpMenu;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
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.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping("/wx")
public class WxController {
    private static final Logger log = LoggerFactory.getLogger(WxController.class);

    @Autowired
    WxMpService wxService;
    @Autowired
    WxMpXmlMessage wxMpXmlMessage;
    @Autowired
    WeChatProperties weChatProperties;

    @RequestMapping(value = "authWx", method = RequestMethod.GET)
    public String authGet(HttpServletRequest request, HttpServletResponse response) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");

        log.info("\n接收到来自微信服务器的认证消息:[signature:{}, timestamp:{}, nonce:{}, echostr:{}]", signature,
                timestamp, nonce, echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }

        if (wxService.checkSignature(timestamp, nonce, signature)) {
            log.info("返回随机字符串表示验证成功,随机字符串:{}", echostr);
            return echostr;
        }

        return "非法请求,验证微信服务器失败";
    }


    @RequestMapping(value = "authWx", method = RequestMethod.POST)
    public String getMessageFromUser(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取用户发送的消息fromXml方法底层已转化为对象
        WxMpXmlMessage message = wxMpXmlMessage.fromXml(request.getInputStream());
        if (com.frkj.common.util.StringUtils.isNull(message)) {
            throw new RuntimeException("解析用户发送的消息失败");
        }
        if (!message.getMsgType().equals(WxConsts.XmlMsgType.EVENT)) {//不是事件
            //TODO 可以选择将消息保存到本地

        }
        log.info("用户发送的消息:{}", message);

        //回复用户消息
        return replyMessage(message);
    }

    public String replyMessage(WxMpXmlMessage message) {
        String out = null;
        switch (message.getMsgType()) {
            case WxConsts.XmlMsgType.TEXT:
                out = dealTextMessage(message);
                break;
            case WxConsts.XmlMsgType.IMAGE:

                break;
            case WxConsts.XmlMsgType.VIDEO:

                break;
            case WxConsts.XmlMsgType.VOICE:

                break;
            case WxConsts.XmlMsgType.NEWS:

                break;
            case WxConsts.XmlMsgType.MUSIC:

                break;
            case WxConsts.XmlMsgType.LOCATION:

                break;
            case WxConsts.XmlMsgType.LINK:

                break;
            case WxConsts.XmlMsgType.EVENT:

                break;

        }
        if (StringUtils.isNotEmpty(out)) {
            return out;
        }
        return "欢迎关注";
    }

    private String dealTextMessage(WxMpXmlMessage message) {
        //TODO 组装回复消息
        String out = null;
        MessageUtils messageUtils = new MessageUtils();
        long time = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        //当用户输入关键词如“1”,“2”等,可以组装特定的响应消息返回给用户
        try {
            if (StringUtils.startsWithAny(message.getContent(), "你好", "1")) {
                WxMpXmlOutTextMessage xmlOutTextMessage = messageUtils.replyTextMessage(message.getFromUser(), message.getToUser(), "欢迎关注");
                //组装回复用户消息
                out = xmlOutTextMessage.toXml();//返回也是xml
                return out;
            }else if (StringUtils.startsWithAny(message.getContent(), "图文")) {
                List<WxMpXmlOutNewsMessage.Item> articles = new ArrayList<>();
                WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
                item.setDescription("微信公众号发送图文消息");
                item.setPicUrl("http://mmbiz.qpic.cn/mmbiz_jpg/DhpEVfrp0gtYNA8lA3py0YBhHxByIJIRUE1J2Hhe8vd6V1lh82PvP4hBFzY6R25AlyO96HJpSRYyF4LYZeqWew/0");
                item.setTitle("正在开发,敬请期待");
                item.setUrl("http://www.baidu.com");
                articles.add(item);
                WxMpXmlOutMessage newsMessage = messageUtils.replyNewsMessage(message.getFromUser(), message.getToUser(), item, articles);
                //组装回复用户消息
                out = newsMessage.toXml();//返回也是xml
                return out;

            }
            //不是关键字
            WxMpXmlOutTextMessage xmlOutTextMessage = messageUtils.replyTextMessage(message.getFromUser(), message.getToUser(), "http://www.baidu.com");
            //组装回复用户消息
            out = xmlOutTextMessage.toXml();//返回也是xml
        } catch (Exception e) {
            e.printStackTrace();
        }
        return out;

    }

    public String dealNewMessage(WxMpXmlMessage message) {

        String out = null;
        MessageUtils messageUtils = new MessageUtils();
        try {

        } catch (Exception e) {
            e.printStackTrace();
        }
        return out;
    }

    /**
     * 创建自定义按钮
     *
     * @param json
     * @return
     * @throws WxErrorException
     */

    @PostMapping("/createByJson")
    public String menuCreate(@RequestBody String json) throws WxErrorException {
        try {
            String s = wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuCreate(json);
            if (StringUtils.isNotEmpty(s)) {
                JSONObject jsonObject = new JSONObject(s);
                if (jsonObject.get("errcode").equals(String.valueOf(0))) {
                    return "创建菜单成功";
                }
                return "创建菜单失败";

            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return null;
    }


    /**
     * 自定义菜单删除接口
     */
    @GetMapping("/delete")
    public void menuDelete() throws WxErrorException {

        try {
            this.wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuDelete();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }

    }

    /**
     * 删除个性化菜单接口
     *
     * @param menuId 个性化菜单的menuid
     */
    @GetMapping("/delete/{menuId}")
    public void menuDelete(@PathVariable String menuId) throws WxErrorException {
        this.wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuDelete(menuId);
    }

    /**
     * 自定义菜单查询接口
     */
    @GetMapping("/get")
    public WxMpMenu menuGet() throws WxErrorException {

        try {
            WxMpMenu wxMpMenu = this.wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuGet();
            if (com.frkj.common.util.StringUtils.isNotNull(wxMpMenu)) {
                log.info("获取菜单列表成功{}", wxMpMenu);
                return wxMpMenu;
            }
            throw new RuntimeException("没有获取到菜单列表");
        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;

    }
}

测试平台申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 获取appId、appSecret

在配置文件 application-dev.yml 中填写获取appId、appSecret           token自定义

wechat:
  config:
    useRedis: true
    #自己测试用的appId及appSecret
    appId: xxxxxxxx
    appSecret: xxxxxxxxxxx
    aesKey: IfDd5twyHOmEzmElMgyNE5mmnh8BRuQ23jXRdajDa7B
    token: 123456
    mpVerify: 6qn27EliDfT1mSYa
    jobTemplateId1: yvv6RNXhtvYRow-w14NhXwc5ZmDDBj23nBETi8zmGNw

打开cmd 窗口运行ngrok.exe http 9999       因为自己项目的端口号是9999

 

 启动成功如下所示

 

 

 

 

启动自己项目 在测试平台接口配配置上 把ngrok获取的http://20de-182-242-18-59.ngrok.io + wechat(项目根路径)+WxController.java中的authWx认证路径(get请求)  填入url

完成url: http://20de-182-242-18-59.ngrok.io/wechat/wx/authWx    

填入自定义token:123456

点击提交按钮 若提示配置成功 则成功介入微信公众测试平台

 

posted on 2022-09-16 17:47  西门夜说  阅读(469)  评论(0编辑  收藏  举报