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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion weixin-java-cp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<!--分布式锁支持-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,125 @@
package me.chanjar.weixin.cp.api.impl;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
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.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;

import java.io.IOException;
import java.util.concurrent.locks.Lock;

import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.GET_AGENT_CONFIG_TICKET;
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.GET_JSAPI_TICKET;

/**
* <pre>
* 默认接口实现类,使用apache httpclient实现
* Created by Binary Wang on 2017-5-27.
* </pre>
* <pre>
* 增加分布式锁(基于WxCpConfigStorage实现)的支持
* Updated by yuanqixun on 2020-05-13
* </pre>
*
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl {
@Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
if (!getWxCpConfigStorage().isAccessTokenExpired() && !forceRefresh) {
return getWxCpConfigStorage().getAccessToken();
}
Lock lock = getWxCpConfigStorage().getAccessTokenLock();
lock.lock();
try {
// 拿到锁之后,再次判断一下最新的token是否过期,避免重刷
if (!getWxCpConfigStorage().isAccessTokenExpired() && !forceRefresh) {
return getWxCpConfigStorage().getAccessToken();
}
String url = String.format(getWxCpConfigStorage().getApiUrl(WxCpApiPathConsts.GET_TOKEN), this.configStorage.getCorpId(), this.configStorage.getCorpSecret());
try {
HttpGet httpGet = new HttpGet(url);
if (getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom()
.setProxy(getRequestHttpProxy()).build();
httpGet.setConfig(config);
}
String resultContent;
try (CloseableHttpClient httpClient = getRequestHttpClient();
CloseableHttpResponse response = httpClient.execute(httpGet)) {
resultContent = new BasicResponseHandler().handleResponse(response);
} finally {
httpGet.releaseConnection();
}
WxError error = WxError.fromJson(resultContent, WxType.CP);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}

WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
getWxCpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
} catch (IOException e) {
throw new RuntimeException(e);
}
} finally {
lock.unlock();
}
return getWxCpConfigStorage().getAccessToken();
}

@Override
public String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) {
getWxCpConfigStorage().expireAgentJsapiTicket();
}
if (getWxCpConfigStorage().isAgentJsapiTicketExpired()) {
Lock lock = getWxCpConfigStorage().getAgentJsapiTicketLock();
lock.lock();
try {
// 拿到锁之后,再次判断一下最新的token是否过期,避免重刷
if (getWxCpConfigStorage().isAgentJsapiTicketExpired()) {
String responseContent = this.get(getWxCpConfigStorage().getApiUrl(GET_AGENT_CONFIG_TICKET), null);
JsonObject jsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
getWxCpConfigStorage().updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(),
jsonObject.get("expires_in").getAsInt());
}
} finally {
lock.unlock();
}
}
return getWxCpConfigStorage().getAgentJsapiTicket();
}

@Override
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) {
getWxCpConfigStorage().expireJsapiTicket();
}

if (getWxCpConfigStorage().isJsapiTicketExpired()) {
Lock lock = getWxCpConfigStorage().getJsapiTicketLock();
lock.lock();
try {
// 拿到锁之后,再次判断一下最新的token是否过期,避免重刷
if (getWxCpConfigStorage().isJsapiTicketExpired()) {
String responseContent = this.get(getWxCpConfigStorage().getApiUrl(GET_JSAPI_TICKET), null);
JsonObject tmpJsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
getWxCpConfigStorage().updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(),
tmpJsonObject.get("expires_in").getAsInt());
}
} finally {
lock.unlock();
}
}
return getWxCpConfigStorage().getJsapiTicket();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;

import java.io.File;
import java.util.concurrent.locks.Lock;

/**
* 微信客户端配置存储.
Expand All @@ -28,6 +29,8 @@ public interface WxCpConfigStorage {

String getAccessToken();

Lock getAccessTokenLock();

boolean isAccessTokenExpired();

/**
Expand All @@ -41,6 +44,8 @@ public interface WxCpConfigStorage {

String getJsapiTicket();

Lock getJsapiTicketLock();

boolean isJsapiTicketExpired();

/**
Expand All @@ -55,6 +60,8 @@ public interface WxCpConfigStorage {

String getAgentJsapiTicket();

Lock getAgentJsapiTicketLock();

boolean isAgentJsapiTicketExpired();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import java.io.File;
import java.io.Serializable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化.
Expand All @@ -22,6 +24,7 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {

private volatile String token;
protected volatile String accessToken;
protected Lock accessTokenLock = new ReentrantLock();
private volatile String aesKey;
protected volatile Integer agentId;
private volatile long expiresTime;
Expand All @@ -34,9 +37,11 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
private volatile String httpProxyPassword;

private volatile String jsapiTicket;
protected Lock jsapiTicketLock = new ReentrantLock();
private volatile long jsapiTicketExpiresTime;

private volatile String agentJsapiTicket;
protected Lock agentJsapiTicketLock = new ReentrantLock();
private volatile long agentJsapiTicketExpiresTime;

private volatile File tmpDirFile;
Expand All @@ -63,6 +68,11 @@ public String getAccessToken() {
return this.accessToken;
}

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

public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
Expand Down Expand Up @@ -93,6 +103,11 @@ public String getJsapiTicket() {
return this.jsapiTicket;
}

@Override
public Lock getJsapiTicketLock() {
return this.jsapiTicketLock;
}

public void setJsapiTicket(String jsapiTicket) {
this.jsapiTicket = jsapiTicket;
}
Expand Down Expand Up @@ -122,6 +137,11 @@ public String getAgentJsapiTicket() {
return this.agentJsapiTicket;
}

@Override
public Lock getAgentJsapiTicketLock() {
return this.agentJsapiTicketLock;
}

@Override
public boolean isAgentJsapiTicketExpired() {
return System.currentTimeMillis() > this.agentJsapiTicketExpiresTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import redis.clients.jedis.JedisPoolConfig;

import java.io.File;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* <pre>
Expand Down Expand Up @@ -89,6 +91,11 @@ public String getAccessToken() {
}
}

@Override
public Lock getAccessTokenLock() {
return new ReentrantLock();
}

@Override
public boolean isAccessTokenExpired() {
try (Jedis jedis = this.jedisPool.getResource()) {
Expand Down Expand Up @@ -132,6 +139,11 @@ public String getJsapiTicket() {
}
}

@Override
public Lock getJsapiTicketLock() {
return new ReentrantLock();
}

@Override
public boolean isJsapiTicketExpired() {
try (Jedis jedis = this.jedisPool.getResource()) {
Expand Down Expand Up @@ -170,6 +182,11 @@ public String getAgentJsapiTicket() {
}
}

@Override
public Lock getAgentJsapiTicketLock() {
return new ReentrantLock();
}

@Override
public boolean isAgentJsapiTicketExpired() {
try (Jedis jedis = this.jedisPool.getResource()) {
Expand Down
Loading