From c5e9f1760780e55041244eaed9715a0c6c2a81a4 Mon Sep 17 00:00:00 2001 From: Sky Date: Mon, 17 Jul 2023 23:24:04 +0800 Subject: [PATCH] =?UTF-8?q?:new:=20#3084=E3=80=90=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E3=80=91=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E7=A8=B3?= =?UTF-8?q?=E5=AE=9A=E7=89=88=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8=E5=87=AD?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/api/impl/BaseWxMpServiceImpl.java | 50 ++++++++++ .../api/impl/WxMpServiceHttpClientImpl.java | 93 ++++++++++++------- .../mp/api/impl/WxMpServiceJoddHttpImpl.java | 63 ++++++------- .../mp/api/impl/WxMpServiceOkHttpImpl.java | 64 ++++++------- .../mp/bean/WxMpStableAccessTokenRequest.java | 32 +++++++ .../weixin/mp/config/WxMpConfigStorage.java | 13 +++ .../mp/config/impl/WxMpDefaultConfigImpl.java | 14 +++ .../chanjar/weixin/mp/enums/WxMpApiUrl.java | 4 + .../mp/api/impl/BaseWxMpServiceImplTest.java | 10 ++ .../mp/api/impl/WxMpServiceImplTest.java | 11 +++ 10 files changed, 251 insertions(+), 103 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpStableAccessTokenRequest.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index b8d1792c2..67d33c6d0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -40,6 +40,7 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.*; @@ -251,6 +252,55 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH return getAccessToken(false); } + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + if (!forceRefresh && !this.getWxMpConfigStorage().isAccessTokenExpired()) { + return this.getWxMpConfigStorage().getAccessToken(); + } + + Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); + boolean locked = false; + try { + do { + locked = lock.tryLock(100, TimeUnit.MILLISECONDS); + if (!forceRefresh && !this.getWxMpConfigStorage().isAccessTokenExpired()) { + return this.getWxMpConfigStorage().getAccessToken(); + } + } while (!locked); + + String response; + if (getWxMpConfigStorage().isStableAccessToken()) { + response = doGetStableAccessTokenRequest(forceRefresh); + } else { + response = doGetAccessTokenRequest(); + } + return extractAccessToken(response); + } catch (IOException | InterruptedException e) { + throw new WxRuntimeException(e); + } finally { + if (locked) { + lock.unlock(); + } + } + } + + /** + * 通过网络请求获取AccessToken + * + * @return . + * @throws IOException . + */ + protected abstract String doGetAccessTokenRequest() throws IOException; + + + /** + * 通过网络请求获取稳定版接口调用凭据 + * + * @return . + * @throws IOException . + */ + protected abstract String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException; + @Override public String shortUrl(String longUrl) throws WxErrorException { if (longUrl.contains("&access_token=")) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java index 8b5e02910..750f78713 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java @@ -1,23 +1,24 @@ package me.chanjar.weixin.mp.api.impl; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.common.error.WxRuntimeException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import me.chanjar.weixin.mp.bean.WxMpStableAccessTokenRequest; import me.chanjar.weixin.mp.config.WxMpConfigStorage; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.CloseableHttpClient; import java.io.IOException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_ACCESS_TOKEN_URL; +import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_STABLE_ACCESS_TOKEN_URL; /** * apache http client方式实现. @@ -64,42 +65,62 @@ public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl this.expiresTime; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java index 6ecf75754..a9255f9dd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java @@ -129,6 +129,10 @@ public interface WxMpApiUrl { * 获取access_token. */ GET_ACCESS_TOKEN_URL(API_DEFAULT_HOST_URL, "/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"), + /** + * 获取稳定版 access_token. + */ + GET_STABLE_ACCESS_TOKEN_URL(API_DEFAULT_HOST_URL, "/cgi-bin/stable_token"), /** * 获得各种类型的ticket. */ diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java index c4b57ff13..89b222405 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java @@ -211,6 +211,16 @@ public class BaseWxMpServiceImplTest { return "模拟一个过期的access token:" + System.currentTimeMillis(); } + @Override + protected String doGetAccessTokenRequest() throws IOException { + return null; + } + + @Override + protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException { + return null; + } + @Override public void initHttp() { diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java index c450775d2..636bedb85 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java @@ -59,4 +59,15 @@ public class WxMpServiceImplTest { Assert.assertNotEquals(before, after); Assert.assertTrue(StringUtils.isNotBlank(after)); } + + public void testStableRefreshAccessToken() throws WxErrorException { + WxMpConfigStorage configStorage = this.wxService.getWxMpConfigStorage(); + configStorage.useStableAccessToken(true); + String before = configStorage.getAccessToken(); + this.wxService.getAccessToken(false); + + String after = configStorage.getAccessToken(); + Assert.assertNotEquals(before, after); + Assert.assertTrue(StringUtils.isNotBlank(after)); + } }