mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-10-29 09:38:19 +08:00
🎨 #2115 优化公众号、小程序、企业微信的access token自动刷新逻辑,避免循环递归调用
This commit is contained in:
@ -241,7 +241,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
|||||||
int retryTimes = 0;
|
int retryTimes = 0;
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
return this.executeInternal(executor, uri, data);
|
return this.executeInternal(executor, uri, data, false);
|
||||||
} catch (WxErrorException e) {
|
} catch (WxErrorException e) {
|
||||||
if (retryTimes + 1 > this.maxRetryTimes) {
|
if (retryTimes + 1 > this.maxRetryTimes) {
|
||||||
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
|
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
|
||||||
@ -271,7 +271,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
|||||||
throw new WxRuntimeException("微信服务端异常,超出重试次数");
|
throw new WxRuntimeException("微信服务端异常,超出重试次数");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh) throws WxErrorException {
|
||||||
E dataForLog = DataUtils.handleDataWithSecret(data);
|
E dataForLog = DataUtils.handleDataWithSecret(data);
|
||||||
|
|
||||||
if (uri.contains("access_token=")) {
|
if (uri.contains("access_token=")) {
|
||||||
@ -291,9 +291,11 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
|||||||
if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {
|
if (WxConsts.ACCESS_TOKEN_ERROR_CODES.contains(error.getErrorCode())) {
|
||||||
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
|
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
|
||||||
this.configStorage.expireAccessToken();
|
this.configStorage.expireAccessToken();
|
||||||
if (this.getWxCpConfigStorage().autoRefreshToken()) {
|
if (this.getWxCpConfigStorage().autoRefreshToken() && !doNotAutoRefresh) {
|
||||||
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
||||||
return this.execute(executor, uri, data);
|
//下一次不再自动重试
|
||||||
|
//当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
|
||||||
|
return this.executeInternal(executor, uri, data, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public class WxCpBusyRetryTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized <T, E> T executeInternal(
|
public synchronized <T, E> T executeInternal(
|
||||||
RequestExecutor<T, E> executor, String uri, E data)
|
RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh)
|
||||||
throws WxErrorException {
|
throws WxErrorException {
|
||||||
log.info("Executed");
|
log.info("Executed");
|
||||||
throw new WxErrorException("something");
|
throw new WxErrorException("something");
|
||||||
|
|||||||
@ -1,13 +1,26 @@
|
|||||||
package me.chanjar.weixin.cp.api.impl;
|
package me.chanjar.weixin.cp.api.impl;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
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.WxErrorException;
|
||||||
|
import me.chanjar.weixin.common.error.WxMpErrorMsgEnum;
|
||||||
|
import me.chanjar.weixin.common.util.http.HttpType;
|
||||||
|
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||||
import me.chanjar.weixin.cp.api.ApiTestModule;
|
import me.chanjar.weixin.cp.api.ApiTestModule;
|
||||||
import me.chanjar.weixin.cp.api.WxCpService;
|
import me.chanjar.weixin.cp.api.WxCpService;
|
||||||
|
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||||
|
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.Guice;
|
import org.testng.annotations.Guice;
|
||||||
import org.testng.annotations.Test;
|
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.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -35,6 +48,61 @@ public class BaseWxCpServiceImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetProviderToken() throws WxErrorException {
|
public void testGetProviderToken() throws WxErrorException {
|
||||||
assertThat(this.wxService.getProviderToken("111","123")).isNotNull();
|
assertThat(this.wxService.getProviderToken("111", "123")).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecuteAutoRefreshToken() throws WxErrorException, IOException {
|
||||||
|
//测试access token获取时的重试机制
|
||||||
|
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
|
||||||
|
BaseWxCpServiceImpl service = new BaseWxCpServiceImpl() {
|
||||||
|
@Override
|
||||||
|
public Object getRequestHttpClient() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getRequestHttpProxy() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpType getRequestType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
|
||||||
|
return "模拟一个过期的access token:" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initHttp() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxCpConfigStorage getWxCpConfigStorage() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
config.setAgentId(1);
|
||||||
|
service.setWxCpConfigStorage(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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -207,7 +207,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
|
|||||||
int retryTimes = 0;
|
int retryTimes = 0;
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
return this.executeInternal(executor, uri, data);
|
return this.executeInternal(executor, uri, data, false);
|
||||||
} catch (WxErrorException e) {
|
} catch (WxErrorException e) {
|
||||||
if (retryTimes + 1 > this.maxRetryTimes) {
|
if (retryTimes + 1 > this.maxRetryTimes) {
|
||||||
log.warn("重试达到最大次数【{}】", maxRetryTimes);
|
log.warn("重试达到最大次数【{}】", maxRetryTimes);
|
||||||
@ -238,7 +238,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
|
|||||||
throw new WxRuntimeException("微信服务端异常,超出重试次数");
|
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);
|
E dataForLog = DataUtils.handleDataWithSecret(data);
|
||||||
|
|
||||||
if (uri.contains("access_token=")) {
|
if (uri.contains("access_token=")) {
|
||||||
@ -271,9 +271,11 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
|
|||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (this.getWxMaConfig().autoRefreshToken()) {
|
if (this.getWxMaConfig().autoRefreshToken() && !doNotAutoRefreshToken) {
|
||||||
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
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.api.WxMaService;
|
||||||
import cn.binarywang.wx.miniapp.config.WxMaConfig;
|
import cn.binarywang.wx.miniapp.config.WxMaConfig;
|
||||||
|
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
|
||||||
import cn.binarywang.wx.miniapp.test.ApiTestModule;
|
import cn.binarywang.wx.miniapp.test.ApiTestModule;
|
||||||
import com.google.inject.Inject;
|
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.WxErrorException;
|
||||||
|
import me.chanjar.weixin.common.error.WxMpErrorMsgEnum;
|
||||||
|
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.Guice;
|
import org.testng.annotations.Guice;
|
||||||
import org.testng.annotations.Test;
|
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.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.testng.Assert.assertNotEquals;
|
import static org.testng.Assert.assertNotEquals;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
@ -101,6 +112,35 @@ public class WxMaServiceImplTest {
|
|||||||
public void testExecute() {
|
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
|
@Test
|
||||||
public void testGetWxMaConfig() {
|
public void testGetWxMaConfig() {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -341,7 +341,7 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
|
|||||||
int retryTimes = 0;
|
int retryTimes = 0;
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
return this.executeInternal(executor, uri, data);
|
return this.executeInternal(executor, uri, data, false);
|
||||||
} catch (WxErrorException e) {
|
} catch (WxErrorException e) {
|
||||||
WxError error = e.getError();
|
WxError error = e.getError();
|
||||||
// -1 系统繁忙, 1000ms后重试
|
// -1 系统繁忙, 1000ms后重试
|
||||||
@ -370,7 +370,7 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
|
|||||||
throw new WxRuntimeException("微信服务端异常,超出重试次数");
|
throw new WxRuntimeException("微信服务端异常,超出重试次数");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh) throws WxErrorException {
|
||||||
E dataForLog = DataUtils.handleDataWithSecret(data);
|
E dataForLog = DataUtils.handleDataWithSecret(data);
|
||||||
|
|
||||||
if (uri.contains("access_token=")) {
|
if (uri.contains("access_token=")) {
|
||||||
@ -399,9 +399,11 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
|
|||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (this.getWxMpConfigStorage().autoRefreshToken()) {
|
if (this.getWxMpConfigStorage().autoRefreshToken() && !doNotAutoRefresh) {
|
||||||
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
||||||
return this.execute(executor, uri, data);
|
//下一次不再自动重试
|
||||||
|
//当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
|
||||||
|
return this.executeInternal(executor, uri, data, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
package me.chanjar.weixin.mp.api;
|
package me.chanjar.weixin.mp.api;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.chanjar.weixin.common.error.WxError;
|
|
||||||
import me.chanjar.weixin.common.error.WxErrorException;
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||||
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl;
|
import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl;
|
||||||
import org.testng.annotations.*;
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@ -23,7 +23,7 @@ public class WxMpBusyRetryTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized <T, E> T executeInternal(
|
public synchronized <T, E> T executeInternal(
|
||||||
RequestExecutor<T, E> executor, String uri, E data)
|
RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh)
|
||||||
throws WxErrorException {
|
throws WxErrorException {
|
||||||
log.info("Executed");
|
log.info("Executed");
|
||||||
throw new WxErrorException("something");
|
throw new WxErrorException("something");
|
||||||
@ -37,7 +37,7 @@ public class WxMpBusyRetryTest {
|
|||||||
|
|
||||||
@Test(dataProvider = "getService", expectedExceptions = RuntimeException.class)
|
@Test(dataProvider = "getService", expectedExceptions = RuntimeException.class)
|
||||||
public void testRetry(WxMpService service) throws WxErrorException {
|
public void testRetry(WxMpService service) throws WxErrorException {
|
||||||
service.execute(null, (String)null, null);
|
service.execute(null, (String) null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "getService")
|
@Test(dataProvider = "getService")
|
||||||
@ -48,7 +48,7 @@ public class WxMpBusyRetryTest {
|
|||||||
try {
|
try {
|
||||||
System.out.println("=====================");
|
System.out.println("=====================");
|
||||||
System.out.println(Thread.currentThread().getName() + ": testRetry");
|
System.out.println(Thread.currentThread().getName() + ": testRetry");
|
||||||
service.execute(null, (String)null, null);
|
service.execute(null, (String) null, null);
|
||||||
} catch (WxErrorException e) {
|
} catch (WxErrorException e) {
|
||||||
throw new WxRuntimeException(e);
|
throw new WxRuntimeException(e);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
|
|||||||
@ -2,27 +2,35 @@ package me.chanjar.weixin.mp.api.impl;
|
|||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import me.chanjar.weixin.common.api.WxConsts;
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||||
import me.chanjar.weixin.common.bean.WxNetCheckResult;
|
import me.chanjar.weixin.common.bean.WxNetCheckResult;
|
||||||
|
import me.chanjar.weixin.common.error.WxError;
|
||||||
import me.chanjar.weixin.common.error.WxErrorException;
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
import me.chanjar.weixin.common.error.WxMpErrorMsgEnum;
|
||||||
|
import me.chanjar.weixin.common.util.http.HttpType;
|
||||||
|
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||||
import me.chanjar.weixin.mp.api.WxMpService;
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
import me.chanjar.weixin.mp.api.test.ApiTestModule;
|
import me.chanjar.weixin.mp.api.test.ApiTestModule;
|
||||||
|
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
|
||||||
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
|
import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.Guice;
|
import org.testng.annotations.Guice;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.*;
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -93,7 +101,7 @@ public class BaseWxMpServiceImplTest {
|
|||||||
|
|
||||||
final int threadNumber = 10;
|
final int threadNumber = 10;
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);
|
ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);
|
||||||
for ( int i = 0; i < threadNumber; i++ ) {
|
for (int i = 0; i < threadNumber; i++) {
|
||||||
executorService.submit(r);
|
executorService.submit(r);
|
||||||
}
|
}
|
||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
@ -190,7 +198,57 @@ public class BaseWxMpServiceImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecute() {
|
public void testExecute() throws WxErrorException, IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecuteAutoRefreshToken() throws WxErrorException, IOException {
|
||||||
|
//测试access token获取时的重试机制
|
||||||
|
BaseWxMpServiceImpl<Object, Object> service = new BaseWxMpServiceImpl() {
|
||||||
|
@Override
|
||||||
|
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
|
||||||
|
return "模拟一个过期的access token:" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initHttp() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getRequestHttpClient() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getRequestHttpProxy() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpType getRequestType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
|
||||||
|
config.setAppId("1");
|
||||||
|
service.setWxMpConfigStorage(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
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user