微信公众号开发记录

微信公众号开发记录


前言

最近开发了微信公众号项目,记录一下一些关键点


一、注册公众号/注册测试号(略)

以下以测试号为例

二、接入微信公众平台开发

1、接口和域名配置

在自己申请的公众号配置验证接口和域名
接口和域名配置

2、验证接口

(1)引入依赖。

// 引入MAVEN依赖
<dependency>
  <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-mp</artifactId>
    <version>4.5.0</version>
</dependency>

(2)配置application.yml

wx:
  mp:
    #callback:如果本地填写穿透地址,如果是服务器填写服务器地址
    callback: https://域名/
    configs:
      - appId: appid#第一个公众号的appid
        secret: appsecret#公众号的appsecret
        token: Token #对应接口配置里的Token值
        #aesKey: sha1 # 接口配置里的EncodingAESKey值,如果是测试号可以不用填写

(3)写WxMpProperties配置类

package com.cdrsd.lzdx.common.configuration;

import cn.hutool.json.JSONUtil;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

/**
* @Description: wechat mp properties
* @Author: SWG
* @Date: 2024/3/23
*/
@Data
@Component
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
    /**
     * 是否使用redis存储access token
     */
    private boolean useRedis;

    /**
     * redis 配置
     */
    private RedisConfig redisConfig;

    @Data
    public static class RedisConfig {
        /**
         * redis服务器 主机地址
         */
        private String host;

        /**
         * redis服务器 端口号
         */
        private Integer port;

        /**
         * redis服务器 密码
         */
        private String password;

        /**
         * redis 服务连接超时时间
         */
        private Integer timeout;
    }

    /**
     * 多个公众号配置信息
     */
    private List<MpConfig> configs;

    @Data
    public static class MpConfig {
        /**
         * 设置微信公众号的appid
         */
        private String appId;

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

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

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

    @Override
    public String toString() {
        return JSONUtil.toJsonStr(this);
    }
}


(4)写WxMpConfig配置类

package com.cdrsd.lzdx.common.configuration;

import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: SWG
 * @description data: 2024/3/21
 */
@Configuration
public class WxMpConfig {
    @Autowired
    WxMpProperties wxMpProperties;

    /**
     * 创建并配置一个用于微信公众号操作的 WxMpService 实例。
     * 该方法读取配置属性并为每个公众号配置创建一个 WxMpDefaultConfigImpl 实例,
     * 将这些实例放入 MultiConfigStorages 中,并返回最终的 WxMpService 实例。
     *
     * @return WxMpService 实例,用于微信公众号操作
     * @throws RuntimeException 如果 wxService 配置异常或 Application 相关配置对象缺失
     */
    @Bean
    public WxMpService wxService() {
        final List<WxMpProperties.MpConfig> configs = wxMpProperties.getConfigs();
        // 检查配置是否存在
        if (configs == null) {
            throw new RuntimeException("wxService配置异常,请检查Application相关配置对象");
        }
        // 创建 WxMpService 实例
        WxMpService service = new WxMpServiceImpl();
        // 配置 MultiConfigStorages
        service.setMultiConfigStorages(
                configs.stream().map(item -> {
                    WxMpDefaultConfigImpl wxMpDefaultConfig = new WxMpDefaultConfigImpl();
                    // 设置公众号的 AppId
                    wxMpDefaultConfig.setAppId(item.getAppId());
                    // 设置公众号的 Secret
                    wxMpDefaultConfig.setSecret(item.getSecret());
                    // 设置公众号的 Token
                    wxMpDefaultConfig.setToken(item.getToken());
                    // 设置公众号的 AesKey
                    wxMpDefaultConfig.setAesKey(item.getAesKey());
                    return wxMpDefaultConfig;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o))
        );

        return service;
    }

}

(5)controller代码`:

// An highlighted block
@RequestMapping("/public")
    public String checkWxServer(@RequestParam Map<String,String> map) {
        System.out.println("开始验证消息是否来自微信服务器,传来的参数{}"+map.toString());
        String signature = map.get("signature");//微信发来的加密字符串
        String echostr = map.get("echostr");//随机字符串
        String timestamp = map.get("timestamp");
        String nonce = map.get("nonce");
        if (StringUtils.isAnyBlank(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }
        //开发者通过检验signature对请求进行校验(下面有校验方式)。
        //若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
        if (wxService.checkSignature(timestamp, nonce, signature)) {
            System.out.println("消息来自微信服务器,验证成功,signature;{}"+signature);
            return echostr;
        }
        System.out.println("消息来自其他服务器,非法请求!!!");
        return "微信非法请求";
    }

3、创建定时任务定时刷新Access token

(1)配置需要的参数

package com.XXX.XXX.common;

public class Constants {
    public static final String tokentype="1";
    //测试公众号APPID
    public static final String appid = "appid";
    //测试公众号appsecret
    public static String secret = "secret";
    //通过code换取网页授权access_token  URL
    public static final String oauth2url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    //获得JSAPIticket URL
    public static String get_jsapiticket_url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKE&type=jsapi";
    //获取accesstoken URL
    public static final String get_accesstoken_url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRECT";

}

(2)WeixinUtil createAccessToken方法和getJsTicket方法

	/**
	* @Description: 根据凭证appid和密钥appsecret生成access_token
	* @return: net.sf.json.JSONObject
	* @Author: SWG
	* @Date: 2024/3/19
	*/
	public static JSONObject createAccessToken() {
		String requestUrl = Constants.get_accesstoken_url.replace("APPID", Constants.appid).replace("SECRECT", Constants.secret);
		String resultstr= HttpRequest.sendGet(requestUrl);
		JSONObject jsonObject = JSONObject.fromObject(resultstr);
		return jsonObject;
	}
	/**
	* 根据access_token生成JsApiTicket
	* @Author: SWG
	* @Date: 2024/3/19
	*/
	public static JSONObject getJsTicket(String accessToken){
		String jsapi_ticketUrl = Constants.get_jsapiticket_url.replace("ACCESS_TOKE", accessToken);
		String jsapi_ticket = HttpRequest.sendGet(jsapi_ticketUrl);
		JSONObject json = JSONObject.fromObject(jsapi_ticket);
		return json;
	}

(2)定时任务

/**
    * @Description: 定时任务定时刷新Access token存到数据库
    * @Author: SWG
    * @Date: 2024/3/23
    */
    @Scheduled(cron = "0 0 0/2 * * ?")
    @PostConstruct
    protected void executeInternal() {
        JSONObject accessTokenTemp = WeixinUtil.createAccessToken();
        try {
            String accessToken = accessTokenTemp.getString("access_token");
            // 取jsapiticket
            JSONObject json = WeixinUtil.getJsTicket(accessToken);
            if (json != null) {
                if(json.getString("ticket")!=null){
                    System.out.println("获取token成功:"+accessToken);
                    // 写入数据库
                    userService.updateToken(Constants.appid, Constants.tokentype, accessToken, json.getString("ticket"));
                }else{
                    System.out.println("wx =====task获取ticket失败");
                }
            } else {
                System.out.println("wx =====task获取ticket失败");
            }
        }catch (JSONException e){
            System.out.println("task没有获取到token"+e.getMessage()+"errcode:"+accessTokenTemp.getString("errcode")+";errmsg:"+accessTokenTemp.getString("errmsg"));
        }
    }

4、创建公众号自定义菜单

先将uniapp前端打包,部署到服务器,得到访问页面的连接,用postMan请求微信服务器,生成自定义菜单,请求需要access_token

(1)uniapp前端打包

正确填写路由模式和基础路径
在这里插入图片描述
打包
在这里插入图片描述

(2)生成自定义菜单

在这里插入图片描述

总结

关键点:
一、接入服务器
二、定时刷新Access token。
三、获取openid进行登录(此项目是有账号密码验证,openid与账号绑定)
四、可以快乐的敲业务代码了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值