Skip to content

【小程序/公众号】提供了获取稳定版获取access token的接口 #3004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public interface WxMaService extends WxService {
* 获取access_token.
*/
String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
String GET_STABLE_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/stable_token";


/**
* The constant JSCODE_TO_SESSION_URL.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,13 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
return this.getWxMaConfig().getAccessToken();
}
} while (!locked);
String response = doGetAccessTokenRequest();

String response;
if (getWxMaConfig().isStableAccessToken()) {
response = doGetStableAccessTokenRequest(forceRefresh);
} else {
response = doGetAccessTokenRequest();
}
return extractAccessToken(response);
} catch (IOException | InterruptedException e) {
throw new WxRuntimeException(e);
Expand All @@ -193,6 +199,15 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
*/
protected abstract String doGetAccessTokenRequest() throws IOException;


/**
* 通过网络请求获取稳定版接口调用凭据
*
* @return .
* @throws IOException .
*/
protected abstract String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException;

@Override
public String get(String url, String queryParam) throws WxErrorException {
return execute(SimpleGetRequestExecutor.create(this), url, queryParam);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaStableAccessTokenRequest;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.util.http.HttpType;
Expand All @@ -11,6 +12,9 @@
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;

Expand Down Expand Up @@ -93,4 +97,40 @@ protected String doGetAccessTokenRequest() throws IOException {
}
}

@Override
protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException {
String url = StringUtils.isNotEmpty(this.getWxMaConfig().getAccessTokenUrl()) ?
this.getWxMaConfig().getAccessTokenUrl() : StringUtils.isNotEmpty(this.getWxMaConfig().getApiHostUrl()) ?
GET_STABLE_ACCESS_TOKEN.replace("https://api.weixin.qq.com", this.getWxMaConfig().getApiHostUrl()) :
GET_STABLE_ACCESS_TOKEN;

HttpPost httpPost = null;
CloseableHttpResponse response = null;
try {
httpPost = new HttpPost(url);
if (this.getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
httpPost.setConfig(config);
}
WxMaStableAccessTokenRequest wxMaAccessTokenRequest = new WxMaStableAccessTokenRequest();
wxMaAccessTokenRequest.setAppid(this.getWxMaConfig().getAppid());
wxMaAccessTokenRequest.setSecret(this.getWxMaConfig().getSecret());
wxMaAccessTokenRequest.setGrantType("client_credential");
wxMaAccessTokenRequest.setForceRefresh(forceRefresh);
httpPost.setEntity(new StringEntity(wxMaAccessTokenRequest.toJson(), ContentType.APPLICATION_JSON));
response = getRequestHttpClient().execute(httpPost);
return new BasicResponseHandler().handleResponse(response);
} finally {
if (httpPost != null) {
httpPost.releaseConnection();
}
if (response != null) {
try {
response.close();
} catch (IOException e) {
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaStableAccessTokenRequest;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.ProxyInfo;
import jodd.http.net.SocketHttpConnectionProvider;
import jodd.net.MimeTypes;
import me.chanjar.weixin.common.util.http.HttpType;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* jodd-http方式实现.
Expand Down Expand Up @@ -62,4 +65,30 @@ protected String doGetAccessTokenRequest() throws IOException {
return request.send().bodyText();
}

@Override
protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException {

String url = StringUtils.isNotEmpty(this.getWxMaConfig().getAccessTokenUrl()) ?
this.getWxMaConfig().getAccessTokenUrl() : StringUtils.isNotEmpty(this.getWxMaConfig().getApiHostUrl()) ?
GET_STABLE_ACCESS_TOKEN.replace("https://api.weixin.qq.com", this.getWxMaConfig().getApiHostUrl()) :
GET_STABLE_ACCESS_TOKEN;

WxMaStableAccessTokenRequest wxMaAccessTokenRequest = new WxMaStableAccessTokenRequest();
wxMaAccessTokenRequest.setAppid(this.getWxMaConfig().getAppid());
wxMaAccessTokenRequest.setSecret(this.getWxMaConfig().getSecret());
wxMaAccessTokenRequest.setGrantType("client_credential");
wxMaAccessTokenRequest.setForceRefresh(forceRefresh);

HttpRequest request = HttpRequest.post(url)
.contentType(MimeTypes.MIME_APPLICATION_JSON, StandardCharsets.UTF_8.name())
.body(wxMaAccessTokenRequest.toJson());
if (this.getRequestHttpProxy() != null) {
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
provider.useProxy(getRequestHttpProxy());

request.withConnectionProvider(provider);
}
return request.send().bodyText();
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaStableAccessTokenRequest;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import me.chanjar.weixin.common.util.http.HttpType;
import me.chanjar.weixin.common.util.http.okhttp.DefaultOkHttpClientBuilder;
Expand Down Expand Up @@ -74,4 +75,22 @@ protected String doGetAccessTokenRequest() throws IOException {
return Objects.requireNonNull(response.body()).string();
}
}

@Override
protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException {
String url = StringUtils.isNotEmpty(this.getWxMaConfig().getAccessTokenUrl()) ?
this.getWxMaConfig().getAccessTokenUrl() : StringUtils.isNotEmpty(this.getWxMaConfig().getApiHostUrl()) ?
GET_STABLE_ACCESS_TOKEN.replace("https://api.weixin.qq.com", this.getWxMaConfig().getApiHostUrl()) :
GET_STABLE_ACCESS_TOKEN;
WxMaStableAccessTokenRequest wxMaAccessTokenRequest = new WxMaStableAccessTokenRequest();
wxMaAccessTokenRequest.setAppid(this.getWxMaConfig().getAppid());
wxMaAccessTokenRequest.setSecret(this.getWxMaConfig().getSecret());
wxMaAccessTokenRequest.setGrantType("client_credential");
wxMaAccessTokenRequest.setForceRefresh(forceRefresh);
RequestBody body = RequestBody.Companion.create(wxMaAccessTokenRequest.toJson(), MediaType.parse("application/json; charset=utf-8"));
Request request = new Request.Builder().url(url).post(body).build();
try (Response response = getRequestHttpClient().newCall(request).execute()) {
return Objects.requireNonNull(response.body()).string();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Data;

import java.io.Serializable;

/**
* 小程序码.
*
* @author Element
* created on 2017/7/27
*/
@Data
public class WxMaStableAccessTokenRequest implements Serializable {

private static final long serialVersionUID = 1L;

@SerializedName("grant_type")
private String grantType = "client_credential";

@SerializedName("appid")
private String appid;
@SerializedName("secret")
private String secret;

@SerializedName("force_refresh")
private boolean forceRefresh;

public String toJson() {
return WxMaGsonBuilder.create().toJson(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ public interface WxMaConfig {
*/
String getAccessToken();

//region 稳定版access token
boolean isStableAccessToken();

void useStableAccessToken(boolean useStableAccessToken);
//endregion


/**
* Gets access token lock.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
import lombok.AccessLevel;
import lombok.Getter;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
Expand All @@ -19,6 +20,13 @@
public class WxMaDefaultConfigImpl implements WxMaConfig {
protected volatile String appid;
protected volatile String token;

/**
* 是否使用稳定版获取accessToken接口
*/
@Getter(value = AccessLevel.NONE)
private boolean useStableAccessToken;

/**
* 小程序原始ID
*/
Expand Down Expand Up @@ -81,6 +89,19 @@ public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

//region 使用稳定版接口获取accessToken
@Override
public boolean isStableAccessToken() {
return this.useStableAccessToken;
}

@Override
public void useStableAccessToken(boolean useStableAccessToken) {
this.useStableAccessToken = useStableAccessToken;
}
//endregion


@Override
public Lock getAccessTokenLock() {
return this.accessTokenLock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public class WxMaServiceImplTest {

@Inject
private WxMaService wxService;
@Inject
private WxMaServiceOkHttpImpl wxMaServiceOkHttp;

public void testRefreshAccessToken() throws WxErrorException {
WxMaConfig configStorage = this.wxService.getWxMaConfig();
Expand All @@ -44,6 +46,16 @@ public void testRefreshAccessToken() throws WxErrorException {
assertTrue(StringUtils.isNotBlank(after));
}

public void testStableRefreshAccessToken() throws WxErrorException {
WxMaConfig configStorage = this.wxMaServiceOkHttp.getWxMaConfig();
configStorage.useStableAccessToken(true);
String before = configStorage.getAccessToken();
this.wxMaServiceOkHttp.getAccessToken(false);
String after = configStorage.getAccessToken();
assertNotEquals(before, after);
assertTrue(StringUtils.isNotBlank(after));
}

@Test(expectedExceptions = {WxErrorException.class})
public void testGetPaidUnionId() throws WxErrorException {
final String unionId = this.wxService.getPaidUnionId("1", null, "3", "4");
Expand Down Expand Up @@ -134,7 +146,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
});
try {
Object execute = service.execute(re, "http://baidu.com", new HashMap<>());
Assert.assertTrue(false, "代码应该不会执行到这里");
Assert.fail("代码应该不会执行到这里");
} catch (WxErrorException e) {
Assert.assertEquals(WxMpErrorMsgEnum.CODE_40001.getCode(), e.getError().getErrorCode());
Assert.assertEquals(2, counter.get());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package cn.binarywang.wx.miniapp.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.locks.ReentrantLock;

import me.chanjar.weixin.common.error.WxRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceOkHttpImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import com.google.inject.Binder;
import com.google.inject.Module;
import me.chanjar.weixin.common.error.WxRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
Expand All @@ -34,6 +34,11 @@ public void configure(Binder binder) {

binder.bind(WxMaService.class).toInstance(wxService);
binder.bind(WxMaConfig.class).toInstance(config);

WxMaServiceOkHttpImpl wxMaServiceOkHttp = new cn.binarywang.wx.miniapp.api.impl.WxMaServiceOkHttpImpl();
wxMaServiceOkHttp.setWxMaConfig(config);
binder.bind(WxMaServiceOkHttpImpl.class).toInstance(wxMaServiceOkHttp);

} catch (IOException e) {
this.log.error(e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@


import cn.binarywang.wx.miniapp.config.WxMaConfig;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.enums.TicketType;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
Expand Down Expand Up @@ -258,6 +261,12 @@ private static class WxOpenInnerConfigStorage implements WxMpConfigStorage, WxMa
private WxMpHostConfig hostConfig;
private String apiHostUrl;
private String accessTokenUrl;
/**
* 是否使用稳定版获取accessToken接口
*/
@Getter(value = AccessLevel.NONE)
@Setter(value = AccessLevel.NONE)
private boolean useStableAccessToken;

/**
* 小程序原始ID
Expand All @@ -284,6 +293,16 @@ public String getAccessToken() {
return wxOpenConfigStorage.getAuthorizerAccessToken(appId);
}

@Override
public boolean isStableAccessToken() {
return this.useStableAccessToken;
}

@Override
public void useStableAccessToken(boolean useStableAccessToken) {
this.useStableAccessToken = useStableAccessToken;
}

@Override
public Lock getAccessTokenLock() {
return this.accessTokenLock;
Expand Down