自定义菜单需要获取Access token
公众号使用AppID和AppSecret调用接口来获取access_token
公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
access_token的有效期是7200秒(两小时),在有效期内,可以一直使用,只有当access_token过期时,才需要再次调用接口 获取access_token。在理想情况下,一个7x24小时运行的系统,每天只需要获取12次access_token,即每2小时获取一次。如果在 有效期内,再次获取access_token,那么上一次获取的access_token将失效。
目前,获取access_token接口的调用频率限制为2000次/天,如果每次发送客服消息、获取用户信息、群发消息之前都要先调用获取 access_token接口得到接口访问凭证,这显然是不合理的,一方面会更耗时(多了一次接口调用操作),另一方面2000次/天的调用限制恐怕也不 够用。因此,在实际应用中,我们需要将获取到的access_token存储起来,然后定期调用access_token接口更新它,以保证随时取出的 access_token都是有效的。
先看完成的例子
接口调用请求说明
https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
参数说明
参数 | 说明 |
---|---|
grant_type | 获取access_token填写client_credential |
appid | 第三方用户唯一凭证 |
secret | 第三方用户唯一凭证密钥,即appsecret |
返回说明
正常情况下,微信会返回下述JSON数据包给公众号:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
参数说明
参数 | 说明 |
---|---|
access_token | 获取到的凭证 |
expires_in | 凭证有效时间,单位:秒 |
封装这两个参数
package com.rzk.pojo;
import lombok.Data;
@Data
public class Token {
private String accessToken;
private int expiresIn;
}
HttpConstant
package com.rzk.util;
public class HttpConstant {
//获取Access token URI
public static String API_URI = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
}
HttpClient 工具类
package com.rzk.util;
import com.rzk.pojo.Token;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class HttpClient {
/**
* GET请求
* @param url
* @return
*/
public static String doGetRequest(String url) {
String result = "";
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
HttpEntity responseEntity = response.getEntity();
result = EntityUtils.toString(responseEntity);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}return result;
}
}
WxServerController
@GetMapping(value = "accessToken")
public String AccessToken(){
Token token = new Token();
//使用httpclient请求
String result = HttpClient.doGetRequest(HttpConstant.API_URI.replace("APPID", environment.getProperty("wx.appid")).replace("APPSECRET", environment.getProperty("wx.secret")));
//转成json对象
JSONObject json = JSON.parseObject(result);
token.setAccessToken(String.valueOf(json.get("access_token")));
return token.getAccessToken();
}
请求accessToken
还要去公众号基础设置开启白名单访问列表,填上你的服务器ip地址即可
整合redis存储accessToken
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rzk</groupId>
<artifactId>wxserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxserver</name>
<description>wxserver</description>
<properties>
<java.version>1.8</java.version>
<httpclient.version>4.5.13</httpclient.version>
<fastjson.version>1.2.76</fastjson.version>
<commons-lang.version>2.6</commons-lang.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml配置文件
配置文件
spring:
redis:
#超过时间
timeout: 10000ms
#地址
host: ip
#端口
port: 6382
#数据库
database: 0
password: 密码
lettuce:
pool:
#最大连接数 默认8
max-active: 1024
# 最大连接阻塞等待时间,默认-1
max-wait: 10000ms
#最大空闲连接
max-idle: 200
#最小空闲连接
min-idle: 5
#哨兵模式
sentinel:
#主节点名称
master: mymaster
#节点
nodes: ip:26381,ip:26382,ip:26383
Controller
@GetMapping(value = "accessToken")
public String getAccessToken(){
Token token = new Token();
//如果不等于空 或者小于600秒
if (redisTemplate.getExpire("expires_in")<600||redisTemplate.getExpire("expires_in")==null){
//使用httpclient请求
String result = HttpClient.doGetRequest(HttpConstant.API_URI.replace("APPID", environment.getProperty("wx.appid")).replace("APPSECRET", environment.getProperty("wx.secret")));
//转成json对象
JSONObject json = JSON.parseObject(result);
System.out.println(json);
token.setAccessToken(String.valueOf(json.get("access_token")));
token.setExpiresIn((Integer) json.get("expires_in"));
System.out.println(json.get("expires_in"));
System.out.println(token.getExpiresIn());
redisTemplate.opsForValue().set("accessToken",json.get("access_token"));
redisTemplate.opsForValue().set("expiresIn",json.get("expires_in"),7200, TimeUnit.SECONDS);
}
String accessToken = redisTemplate.opsForValue().get("accessToken").toString();
Long expiresIn = redisTemplate.getExpire("expiresIn");
logger.info("accessToken{}:"+accessToken);
logger.info("expiresIn{}:"+expiresIn);
return token.getAccessToken();
}
我使用redis流程
后续可用springboot自带的定时任务处理器去开启定时任务功能
这里就不贴定时任务的代码了