mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-10-29 17:48:50 +08:00
🎨 #2115 优化公众号、小程序、企业微信的access token自动刷新逻辑,避免循环递归调用
This commit is contained in:
@ -207,7 +207,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
|
||||
int retryTimes = 0;
|
||||
do {
|
||||
try {
|
||||
return this.executeInternal(executor, uri, data);
|
||||
return this.executeInternal(executor, uri, data, false);
|
||||
} catch (WxErrorException e) {
|
||||
if (retryTimes + 1 > this.maxRetryTimes) {
|
||||
log.warn("重试达到最大次数【{}】", maxRetryTimes);
|
||||
@ -238,7 +238,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
|
||||
throw new WxRuntimeException("微信服务端异常,超出重试次数");
|
||||
}
|
||||
|
||||
private <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
||||
private <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefreshToken) throws WxErrorException {
|
||||
E dataForLog = DataUtils.handleDataWithSecret(data);
|
||||
|
||||
if (uri.contains("access_token=")) {
|
||||
@ -271,9 +271,11 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
if (this.getWxMaConfig().autoRefreshToken()) {
|
||||
if (this.getWxMaConfig().autoRefreshToken() && !doNotAutoRefreshToken) {
|
||||
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
||||
return this.execute(executor, uri, data);
|
||||
//下一次不再自动重试
|
||||
//当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
|
||||
return this.executeInternal(executor, uri, data, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,14 +2,25 @@ package cn.binarywang.wx.miniapp.api.impl;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||
import cn.binarywang.wx.miniapp.config.WxMaConfig;
|
||||
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
|
||||
import cn.binarywang.wx.miniapp.test.ApiTestModule;
|
||||
import com.google.inject.Inject;
|
||||
import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.error.WxMpErrorMsgEnum;
|
||||
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.mockito.Mockito;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
@ -101,6 +112,35 @@ public class WxMaServiceImplTest {
|
||||
public void testExecute() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteAutoRefreshToken() throws WxErrorException, IOException {
|
||||
//测试access token获取时的重试机制
|
||||
WxMaServiceImpl service = new WxMaServiceImpl() {
|
||||
@Override
|
||||
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
|
||||
return "模拟一个过期的access token:" + System.currentTimeMillis();
|
||||
}
|
||||
};
|
||||
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
|
||||
config.setAppid("1");
|
||||
service.setWxMaConfig(config);
|
||||
RequestExecutor<Object, Object> re = mock(RequestExecutor.class);
|
||||
|
||||
AtomicInteger counter = new AtomicInteger();
|
||||
Mockito.when(re.execute(Mockito.anyString(), Mockito.any(), Mockito.any())).thenAnswer(invocation -> {
|
||||
counter.incrementAndGet();
|
||||
WxError error = WxError.builder().errorCode(WxMpErrorMsgEnum.CODE_40001.getCode()).errorMsg(WxMpErrorMsgEnum.CODE_40001.getMsg()).build();
|
||||
throw new WxErrorException(error);
|
||||
});
|
||||
try {
|
||||
Object execute = service.execute(re, "http://baidu.com", new HashMap<>());
|
||||
Assert.assertTrue(false, "代码应该不会执行到这里");
|
||||
} catch (WxErrorException e) {
|
||||
Assert.assertEquals(WxMpErrorMsgEnum.CODE_40001.getCode(), e.getError().getErrorCode());
|
||||
Assert.assertEquals(2, counter.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWxMaConfig() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user