weixin-java-miniapp vs getStableAccessToken
🏷️ 微信
微信小程序提供的很多 API 都需要接口调用凭据,但获取时每次都会自动刷新凭据 [1],这就导致如果项目有多个环境(如测试和生产环境)时会导致有一个环境的凭据不可用。之前的做法都是把测试环境的凭据获取处理通过开关关掉,这样就会导致测试环境某些功能没法正常使用。
最近在开发小程序后端服务时发现微信提供了一个获取稳定版接口调用凭据的 API,和之前的区别就是多次获取时不再每次都刷新,完美解决了上面的问题。
这个新的 API 应该已经提供了有一段时间了,只是这两年没有做小程序的项目,也就没注意到。
weixin-java-miniapp
4.5.0
SpringBoot 开发中一般都是用开源组件 weixin-java-miniapp 。项目开始时(2023 年 12 月)最新版还是 4.5.0 ,没有提供获取稳定版接口调用凭据的 API,但是可以通过重写 WxMaServiceImpl
的 doGetAccessTokenRequest()
来改为使用稳定版的调用凭据。
代码示例:
java
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import java.io.IOException;
public class MyWxMaServiceImpl extends WxMaServiceImpl {
public static final String GET_STABLE_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/stable_token";
@Override
protected String doGetAccessTokenRequest() throws IOException {
HttpPost httpPost = null;
CloseableHttpResponse response = null;
try {
httpPost = new HttpPost(GET_STABLE_ACCESS_TOKEN_URL);
if (this.getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
httpPost.setConfig(config);
}
httpPost.setEntity(new StringEntity("{\"grant_type\":\"client_credential\",\"appid\":\"%s\",\"secret\":\"%s\"}"
.formatted(this.getWxMaConfig().getAppid(), this.getWxMaConfig().getSecret())));
response = getRequestHttpClient().execute(httpPost);
return new BasicResponseHandler().handleResponse(response);
} finally {
if (httpPost != null) {
httpPost.releaseConnection();
}
if (response != null) {
try {
response.close();
} catch (IOException e) {
}
}
}
}
}
4.6.0
最近偶然发现 weixin-java-miniapp 更新到了 4.6.0 版,就看了一下更新日志 [2],发现已经提供了对应的选项。
- #2998 增加获取稳定版接口调用凭据的接口,通过设置
WxMaConfig#useStableAccessToken
方法去开启使用稳定版接口
这个版本也是在 2023 年 12 月更新的,不过是在月底,项目已经开始了一段时间了。
代码示例:
java
WxMaService maService = new WxMaServiceImpl();
maService.setMultiConfigs(
clients.stream()
.map(a -> {
WxMaDefaultConfigImpl config = new WxMaRedissonConfigImpl(redissonClient);
config.useStableAccessToken(true);
config.setAppid(a.getClientKey());
config.setSecret(a.getClientSecret());
if (JSONUtil.isTypeJSON(a.getExtraSetting())) {
JSONObject extraSetting = JSONUtil.parseObj(a.getExtraSetting());
config.setToken(extraSetting.getStrEscaped("token", ""));
config.setAesKey(extraSetting.getStrEscaped("aesKey", ""));
config.setMsgDataFormat(extraSetting.getStrEscaped("msgDataFormat", "XML"));
}
return config;
}).collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, a -> a, (o, n) -> o)));
return maService;