出现40014的access_token问题时需要自动刷新token #197

This commit is contained in:
Binary Wang 2017-04-28 10:46:26 +08:00
parent 19b3b991f9
commit 67a846b325
5 changed files with 31 additions and 39 deletions

View File

@ -1,18 +1,7 @@
package me.chanjar.weixin.cp.api.impl; package me.chanjar.weixin.cp.api.impl;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.*; import com.google.gson.*;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.menu.WxMenu; import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxError;
@ -33,10 +22,19 @@ import me.chanjar.weixin.cp.bean.WxCpMessage;
import me.chanjar.weixin.cp.bean.WxCpTag; import me.chanjar.weixin.cp.bean.WxCpTag;
import me.chanjar.weixin.cp.bean.WxCpUser; import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractWxCpService<H, P> implements WxCpService, RequestHttp<H, P> { import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
protected final Logger log = LoggerFactory.getLogger(AbstractWxCpService.class); public abstract class AbstractWxCpServiceImpl<H, P> implements WxCpService, RequestHttp<H, P> {
protected final Logger log = LoggerFactory.getLogger(AbstractWxCpServiceImpl.class);
/** /**
* 全局的是否正在刷新access token的锁 * 全局的是否正在刷新access token的锁
@ -493,9 +491,7 @@ public abstract class AbstractWxCpService<H, P> implements WxCpService, RequestH
int retryTimes = 0; int retryTimes = 0;
do { do {
try { try {
T result = this.executeInternal(executor, uri, data); return this.executeInternal(executor, uri, data);
this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",uri, data, result);
return result;
} catch (WxErrorException e) { } catch (WxErrorException e) {
if (retryTimes + 1 > this.maxRetryTimes) { if (retryTimes + 1 > this.maxRetryTimes) {
this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
@ -525,37 +521,39 @@ public abstract class AbstractWxCpService<H, P> implements WxCpService, RequestH
throw new RuntimeException("微信服务端异常,超出重试次数"); throw new RuntimeException("微信服务端异常,超出重试次数");
} }
public synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { private synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
if (uri.contains("access_token=")) { if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
} }
String accessToken = getAccessToken(false); String accessToken = getAccessToken(false);
String uriWithAccessToken = uri; String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;
try { try {
return executor.execute(this, uriWithAccessToken, data); T result = executor.execute(this, uriWithAccessToken, data);
this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uriWithAccessToken, data, result);
return result;
} catch (WxErrorException e) { } catch (WxErrorException e) {
WxError error = e.getError(); WxError error = e.getError();
/* /*
* 发生以下情况时尝试刷新access_token * 发生以下情况时尝试刷新access_token
* 40001 获取access_token时AppSecret错误或者access_token无效 * 40001 获取access_token时AppSecret错误或者access_token无效
* 42001 access_token超时 * 42001 access_token超时
* 40014 不合法的access_token请开发者认真比对access_token的有效性如是否过期或查看是否正在为恰当的公众号调用接口
*/ */
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
// 强制设置wxCpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token // 强制设置wxCpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token
this.configStorage.expireAccessToken(); this.configStorage.expireAccessToken();
return execute(executor, uri, data); return execute(executor, uri, data);
} }
if (error.getErrorCode() != 0) { if (error.getErrorCode() != 0) {
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, error); this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uriWithAccessToken, data, error);
throw new WxErrorException(error); throw new WxErrorException(error);
} }
return null; return null;
} catch (IOException e) { } catch (IOException e) {
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", uri, data, e.getMessage()); this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", uriWithAccessToken, data, e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@ -7,7 +7,7 @@ import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
import me.chanjar.weixin.cp.api.WxCpConfigStorage; import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.impl.AbstractWxCpService; import me.chanjar.weixin.cp.api.impl.AbstractWxCpServiceImpl;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
@ -18,7 +18,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
import java.io.IOException; import java.io.IOException;
public class WxCpServiceImpl extends AbstractWxCpService<CloseableHttpClient, HttpHost> { public class WxCpServiceImpl extends AbstractWxCpServiceImpl<CloseableHttpClient, HttpHost> {
protected CloseableHttpClient httpClient; protected CloseableHttpClient httpClient;
protected HttpHost httpProxy; protected HttpHost httpProxy;

View File

@ -5,9 +5,9 @@ import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpConfigStorage; import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.impl.AbstractWxCpService; import me.chanjar.weixin.cp.api.impl.AbstractWxCpServiceImpl;
public class WxCpServiceImpl extends AbstractWxCpService<HttpConnectionProvider, ProxyInfo> { public class WxCpServiceImpl extends AbstractWxCpServiceImpl<HttpConnectionProvider, ProxyInfo> {
protected HttpConnectionProvider httpClient; protected HttpConnectionProvider httpClient;
protected ProxyInfo httpProxy; protected ProxyInfo httpProxy;

View File

@ -2,16 +2,15 @@ package me.chanjar.weixin.cp.api.impl.okhttp;
import java.io.IOException; import java.io.IOException;
import jodd.http.*;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo;
import me.chanjar.weixin.cp.api.WxCpConfigStorage; import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.impl.AbstractWxCpService; import me.chanjar.weixin.cp.api.impl.AbstractWxCpServiceImpl;
import okhttp3.*; import okhttp3.*;
public class WxCpServiceImpl extends AbstractWxCpService<ConnectionPool, OkhttpProxyInfo> { public class WxCpServiceImpl extends AbstractWxCpServiceImpl<ConnectionPool, OkhttpProxyInfo> {
protected ConnectionPool httpClient; protected ConnectionPool httpClient;
protected OkhttpProxyInfo httpProxy; protected OkhttpProxyInfo httpProxy;

View File

@ -292,8 +292,7 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ
int retryTimes = 0; int retryTimes = 0;
do { do {
try { try {
T result = executeInternal(executor, uri, data); return this.executeInternal(executor, uri, data);
return result;
} catch (WxErrorException e) { } catch (WxErrorException e) {
if (retryTimes + 1 > this.maxRetryTimes) { if (retryTimes + 1 > this.maxRetryTimes) {
this.log.warn("重试达到最大次数【{}】", maxRetryTimes); this.log.warn("重试达到最大次数【{}】", maxRetryTimes);
@ -327,12 +326,7 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ
} }
String accessToken = getAccessToken(false); String accessToken = getAccessToken(false);
String uriWithAccessToken; String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
if (uri.contains("?")) {
uriWithAccessToken = uri + "&access_token=" + accessToken;
} else {
uriWithAccessToken = uri + "?access_token=" + accessToken;
}
try { try {
T result = executor.execute(this, uriWithAccessToken, data); T result = executor.execute(this, uriWithAccessToken, data);
@ -344,8 +338,9 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ
* 发生以下情况时尝试刷新access_token * 发生以下情况时尝试刷新access_token
* 40001 获取access_token时AppSecret错误或者access_token无效 * 40001 获取access_token时AppSecret错误或者access_token无效
* 42001 access_token超时 * 42001 access_token超时
* 40014 不合法的access_token请开发者认真比对access_token的有效性如是否过期或查看是否正在为恰当的公众号调用接口
*/ */
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
// 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token // 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token
this.getWxMpConfigStorage().expireAccessToken(); this.getWxMpConfigStorage().expireAccessToken();
if (this.getWxMpConfigStorage().autoRefreshToken()) { if (this.getWxMpConfigStorage().autoRefreshToken()) {