@@ -109,6 +109,11 @@ | |||
<artifactId>jetty-servlet</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.assertj</groupId> | |||
<artifactId>assertj-guava</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
@@ -0,0 +1,24 @@ | |||
package me.chanjar.weixin.common.util; | |||
import org.apache.commons.lang3.StringUtils; | |||
/** | |||
* <pre> | |||
* 数据处理工具类 | |||
* Created by BinaryWang on 2018/5/8. | |||
* </pre> | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class DataUtils { | |||
/** | |||
* 将数据中包含的secret字符使用星号替换,防止日志打印时被输出 | |||
*/ | |||
public static <E> E handleDataWithSecret(E data) { | |||
E dataForLog = data; | |||
if(data instanceof String && StringUtils.contains((String)data, "&secret=")){ | |||
dataForLog = (E) StringUtils.replaceAll((String)data,"&secret=\\w+&","&secret=******&"); | |||
} | |||
return dataForLog; | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
package me.chanjar.weixin.common.util; | |||
import org.testng.annotations.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.testng.Assert.*; | |||
/** | |||
* <pre> | |||
* Created by BinaryWang on 2018/5/8. | |||
* </pre> | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class DataUtilsTest { | |||
@Test | |||
public void testHandleDataWithSecret() { | |||
String data = "js_code=001tZveq0SMoiq1AEXeq0ECJeq0tZveZ&secret=5681022fa1643845392367ea88888888&grant_type=authorization_code&appid=wxe156d4848d999999"; | |||
final String s = DataUtils.handleDataWithSecret(data); | |||
assertThat(s).contains("&secret=******&"); | |||
} | |||
} |
@@ -5,13 +5,12 @@ import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.bean.menu.WxMenu; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.session.StandardSessionManager; | |||
import me.chanjar.weixin.common.session.WxSession; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.DataUtils; | |||
import me.chanjar.weixin.common.util.RandomUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
@@ -21,14 +20,11 @@ import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.cp.api.*; | |||
import me.chanjar.weixin.cp.bean.*; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.List; | |||
public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, RequestHttp<H, P> { | |||
protected final Logger log = LoggerFactory.getLogger(this.getClass()); | |||
@@ -201,6 +197,8 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||
} | |||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||
E dataForLog = DataUtils.handleDataWithSecret(data); | |||
if (uri.contains("access_token=")) { | |||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | |||
} | |||
@@ -210,7 +208,7 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||
try { | |||
T result = executor.execute(uriWithAccessToken, data); | |||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); | |||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||
return result; | |||
} catch (WxErrorException e) { | |||
WxError error = e.getError(); | |||
@@ -227,12 +225,12 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||
} | |||
if (error.getErrorCode() != 0) { | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); | |||
throw new WxErrorException(error, e); | |||
} | |||
return null; | |||
} catch (IOException e) { | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
@@ -16,6 +16,7 @@ import com.google.common.base.Joiner; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.DataUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.http.HttpType; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
@@ -24,6 +25,7 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.config.RequestConfig; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
@@ -38,6 +40,9 @@ import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.concurrent.locks.Lock; | |||
import static cn.binarywang.wx.miniapp.constant.WxMaConstants.*; | |||
import static cn.binarywang.wx.miniapp.constant.WxMaConstants.ErrorCode.*; | |||
/** | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@@ -212,7 +217,9 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||
throw new RuntimeException("微信服务端异常,超出重试次数"); | |||
} | |||
public <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) throws WxErrorException { | |||
E dataForLog = DataUtils.handleDataWithSecret(data); | |||
if (uri.contains("access_token=")) { | |||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | |||
} | |||
@@ -222,16 +229,16 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||
try { | |||
T result = executor.execute(uriWithAccessToken, data); | |||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); | |||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||
return result; | |||
} catch (WxErrorException e) { | |||
WxError error = e.getError(); | |||
/* | |||
* 发生以下情况时尝试刷新access_token | |||
*/ | |||
if (error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40001 | |||
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_42001 | |||
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40014) { | |||
if (error.getErrorCode() == ERR_40001 | |||
|| error.getErrorCode() == ERR_42001 | |||
|| error.getErrorCode() == ERR_40014) { | |||
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | |||
this.getWxMaConfig().expireAccessToken(); | |||
if (this.getWxMaConfig().autoRefreshToken()) { | |||
@@ -240,12 +247,12 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||
} | |||
if (error.getErrorCode() != 0) { | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); | |||
throw new WxErrorException(error, e); | |||
} | |||
return null; | |||
} catch (IOException e) { | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
@@ -9,6 +9,7 @@ import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.session.StandardSessionManager; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.DataUtils; | |||
import me.chanjar.weixin.common.util.RandomUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.http.*; | |||
@@ -265,6 +266,8 @@ public abstract class WxMpServiceBaseImpl<H, P> implements WxMpService, RequestH | |||
} | |||
public <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||
E dataForLog = DataUtils.handleDataWithSecret(data); | |||
if (uri.contains("access_token=")) { | |||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | |||
} | |||
@@ -275,7 +278,7 @@ public abstract class WxMpServiceBaseImpl<H, P> implements WxMpService, RequestH | |||
try { | |||
T result = executor.execute(uriWithAccessToken, data); | |||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); | |||
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||
return result; | |||
} catch (WxErrorException e) { | |||
WxError error = e.getError(); | |||
@@ -294,12 +297,12 @@ public abstract class WxMpServiceBaseImpl<H, P> implements WxMpService, RequestH | |||
} | |||
if (error.getErrorCode() != 0) { | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); | |||
throw new WxErrorException(error, e); | |||
} | |||
return null; | |||
} catch (IOException e) { | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); | |||
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); | |||
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); | |||
} | |||
} | |||