:art: 优化微信支付请求代码,抽取合并重复代码

This commit is contained in:
Binary Wang
2025-04-26 11:18:56 +08:00
parent cbb3b24577
commit 2279105fef
3 changed files with 65 additions and 103 deletions

View File

@@ -64,8 +64,6 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
private static final Gson GSON = new GsonBuilder().create();
final Logger log = LoggerFactory.getLogger(this.getClass());
static ThreadLocal<WxPayApiData> wxApiData = new ThreadLocal<>();

View File

@@ -6,6 +6,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.v3.WxPayV3DownloadHttpGet;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.util.json.GsonParser;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
@@ -39,12 +40,13 @@ import java.util.Optional;
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Slf4j
public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
private static final String ACCEPT = "Accept";
private static final String CONTENT_TYPE = "Content-Type";
private static final String APPLICATION_JSON = "application/json";
private static final String WECHATPAY_SERIAL = "Wechatpay-Serial";
private static final String WECHAT_PAY_SERIAL = "Wechatpay-Serial";
@Override
public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException {
@@ -55,7 +57,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
final byte[] bytes = EntityUtils.toByteArray(response.getEntity());
final String responseData = Base64.getEncoder().encodeToString(bytes);
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据(Base64编码后)】:{}", url, requestStr, responseData);
this.logRequestAndResponse(url, requestStr, responseData);
wxApiData.set(new WxPayApiData(url, requestStr, responseData, null));
return bytes;
}
@@ -63,7 +65,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
httpPost.releaseConnection();
}
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
this.logError( url, requestStr, e);
wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage()));
throw new WxPayException(e.getMessage(), e);
}
@@ -77,7 +79,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
this.logRequestAndResponse(url, requestStr, responseString);
if (this.getConfig().isIfSaveApiData()) {
wxApiData.set(new WxPayApiData(url, requestStr, responseString, null));
}
@@ -87,7 +89,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
httpPost.releaseConnection();
}
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
this.logError(url, requestStr, e);
if (this.getConfig().isIfSaveApiData()) {
wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage()));
}
@@ -97,13 +99,14 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
@Override
public String postV3(String url, String requestStr) throws WxPayException {
CloseableHttpClient httpClient = this.createApiV3HttpClient();
HttpPost httpPost = this.createHttpPost(url, requestStr);
httpPost.addHeader(ACCEPT, APPLICATION_JSON);
httpPost.addHeader(CONTENT_TYPE, APPLICATION_JSON);
String serialNumber = getWechatpaySerial(getConfig());
httpPost.addHeader(WECHATPAY_SERIAL, serialNumber);
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
this.configureRequest(httpPost);
return this.requestV3(url, requestStr, httpPost);
}
private String requestV3(String url, String requestStr, HttpRequestBase httpRequestBase) throws WxPayException {
try (CloseableHttpClient httpClient = this.createApiV3HttpClient();
CloseableHttpResponse response = httpClient.execute(httpRequestBase)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
//post方法有可能会没有返回值的情况
@@ -113,7 +116,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
}
if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) {
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
this.logRequestAndResponse(url, requestStr, responseString);
return responseString;
}
@@ -121,65 +124,26 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
JsonObject jsonObject = GsonParser.parse(responseString);
throw convertException(jsonObject);
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
this.logError(url, requestStr, e);
throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e);
} finally {
httpPost.releaseConnection();
httpRequestBase.releaseConnection();
}
}
@Override
public String patchV3(String url, String requestStr) throws WxPayException {
CloseableHttpClient httpClient = this.createApiV3HttpClient();
HttpPatch httpPatch = new HttpPatch(url);
String serialNumber = getWechatpaySerial(getConfig());
httpPatch.addHeader(WECHATPAY_SERIAL, serialNumber);
httpPatch.setEntity(this.createEntry(requestStr));
httpPatch.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout())
.setConnectTimeout(this.getConfig().getHttpConnectionTimeout())
.setSocketTimeout(this.getConfig().getHttpTimeout())
.build());
httpPatch.addHeader(ACCEPT, APPLICATION_JSON);
httpPatch.addHeader(CONTENT_TYPE, APPLICATION_JSON);
try (CloseableHttpResponse response = httpClient.execute(httpPatch)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
//post方法有可能会没有返回值的情况
String responseString = null;
if (response.getEntity() != null) {
responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) {
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
return responseString;
}
//有错误提示信息返回
JsonObject jsonObject = GsonParser.parse(responseString);
throw convertException(jsonObject);
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e);
} finally {
httpPatch.releaseConnection();
}
return this.requestV3(url, requestStr, httpPatch);
}
@Override
public String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException {
CloseableHttpClient httpClient = this.createApiV3HttpClient();
HttpPost httpPost = this.createHttpPost(url, requestStr);
httpPost.addHeader(ACCEPT, APPLICATION_JSON);
httpPost.addHeader(CONTENT_TYPE, APPLICATION_JSON);
String serialNumber = getWechatpaySerial(getConfig());
httpPost.addHeader("Wechatpay-Serial", serialNumber);
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
this.configureRequest(httpPost);
try (CloseableHttpClient httpClient = this.createApiV3HttpClient();
CloseableHttpResponse response = httpClient.execute(httpPost)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
String responseString = "{}";
@@ -189,7 +153,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
}
if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) {
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
this.logRequestAndResponse(url, requestStr, responseString);
return responseString;
}
@@ -197,8 +161,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
JsonObject jsonObject = GsonParser.parse(responseString);
throw convertException(jsonObject);
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
e.printStackTrace();
this.logError(url, requestStr, e);
throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e);
} finally {
httpPost.releaseConnection();
@@ -207,21 +170,17 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
@Override
public String postV3(String url, HttpPost httpPost) throws WxPayException {
String serialNumber = getWechatpaySerial(getConfig());
httpPost.addHeader(WECHATPAY_SERIAL, serialNumber);
String serialNumber = getWechatPaySerial(getConfig());
httpPost.addHeader(WECHAT_PAY_SERIAL, serialNumber);
return this.requestV3(url, httpPost);
}
@Override
public String requestV3(String url, HttpRequestBase httpRequest) throws WxPayException {
httpRequest.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout())
.setConnectTimeout(this.getConfig().getHttpConnectionTimeout())
.setSocketTimeout(this.getConfig().getHttpTimeout())
.build());
this.configureRequest(httpRequest);
CloseableHttpClient httpClient = this.createApiV3HttpClient();
try (CloseableHttpResponse response = httpClient.execute(httpRequest)) {
try (CloseableHttpClient httpClient = this.createApiV3HttpClient();
CloseableHttpResponse response = httpClient.execute(httpRequest)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
//post方法有可能会没有返回值的情况
@@ -252,38 +211,30 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
return getV3WithWechatPaySerial(url);
}
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader(ACCEPT, APPLICATION_JSON);
httpGet.addHeader(CONTENT_TYPE, APPLICATION_JSON);
String serialNumber = getWechatpaySerial(getConfig());
httpGet.addHeader(WECHATPAY_SERIAL, serialNumber);
return this.requestV3(url, httpGet);
}
@Override
public String getV3WithWechatPaySerial(String url) throws WxPayException {
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader(ACCEPT, APPLICATION_JSON);
httpGet.addHeader(CONTENT_TYPE, APPLICATION_JSON);
String serialNumber = getWechatpaySerial(getConfig());
httpGet.addHeader(WECHATPAY_SERIAL, serialNumber);
return this.requestV3(url, httpGet);
}
@Override
public InputStream downloadV3(String url) throws WxPayException {
CloseableHttpClient httpClient = this.createApiV3HttpClient();
HttpGet httpGet = new WxPayV3DownloadHttpGet(url);
httpGet.addHeader(ACCEPT, ContentType.WILDCARD.getMimeType());
String serialNumber = getWechatpaySerial(getConfig());
httpGet.addHeader(WECHATPAY_SERIAL, serialNumber);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
String serialNumber = getWechatPaySerial(getConfig());
httpGet.addHeader(WECHAT_PAY_SERIAL, serialNumber);
try (CloseableHttpClient httpClient = this.createApiV3HttpClient();
CloseableHttpResponse response = httpClient.execute(httpGet)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
Header contentType = response.getFirstHeader(HttpHeaders.CONTENT_TYPE);
boolean isJsonContentType = Objects.nonNull(contentType) && ContentType.APPLICATION_JSON.getMimeType()
.equals(ContentType.parse(String.valueOf(contentType.getValue())).getMimeType());
if ((HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) && !isJsonContentType) {
this.log.info("\n【请求地址】{}\n", url);
log.info("\n【请求地址】{}\n", url);
return response.getEntity().getContent();
}
@@ -293,7 +244,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
JsonObject jsonObject = GsonParser.parse(responseString);
throw convertException(jsonObject);
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【异常信息】{}", url, e.getMessage());
log.error("\n【请求地址】{}\n【异常信息】{}", url, e.getMessage());
throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e);
} finally {
httpGet.releaseConnection();
@@ -305,23 +256,28 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
HttpPut httpPut = new HttpPut(url);
StringEntity entity = this.createEntry(requestStr);
httpPut.setEntity(entity);
httpPut.addHeader(ACCEPT, APPLICATION_JSON);
httpPut.addHeader(CONTENT_TYPE, APPLICATION_JSON);
String serialNumber = getWechatpaySerial(getConfig());
httpPut.addHeader(WECHATPAY_SERIAL, serialNumber);
return requestV3(url, httpPut);
}
@Override
public String deleteV3(String url) throws WxPayException {
HttpDelete httpDelete = new HttpDelete(url);
httpDelete.addHeader(ACCEPT, APPLICATION_JSON);
httpDelete.addHeader(CONTENT_TYPE, APPLICATION_JSON);
String serialNumber = getWechatpaySerial(getConfig());
httpDelete.addHeader(WECHATPAY_SERIAL, serialNumber);
return requestV3(url, httpDelete);
}
private void configureRequest(HttpRequestBase request) {
String serialNumber = getWechatPaySerial(getConfig());
request.addHeader(ACCEPT, APPLICATION_JSON);
request.addHeader(CONTENT_TYPE, APPLICATION_JSON);
request.addHeader(WECHAT_PAY_SERIAL, serialNumber);
request.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout())
.setConnectTimeout(this.getConfig().getHttpConnectionTimeout())
.setSocketTimeout(this.getConfig().getHttpTimeout())
.build());
}
private CloseableHttpClient createApiV3HttpClient() throws WxPayException {
CloseableHttpClient apiV3HttpClient = this.getConfig().getApiV3HttpClient();
if (null == apiV3HttpClient) {
@@ -387,7 +343,6 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
new DefaultHostnameVerifier()));
}
private WxPayException convertException(JsonObject jsonObject) {
//todo 这里考虑使用新的适用于V3的异常
JsonElement codeElement = jsonObject.get("code");
@@ -401,13 +356,20 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
/**
* 兼容微信支付公钥模式
* @param wxPayConfig
* @return
*/
private String getWechatpaySerial(WxPayConfig wxPayConfig) {
private String getWechatPaySerial(WxPayConfig wxPayConfig) {
if (StringUtils.isNotBlank(wxPayConfig.getPublicKeyId())) {
return wxPayConfig.getPublicKeyId();
}
return wxPayConfig.getVerifier().getValidCertificate().getSerialNumber().toString(16).toUpperCase();
}
private void logRequestAndResponse(String url, String requestStr, String responseStr) {
log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseStr);
}
private void logError(String url, String requestStr, Exception e) {
log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
}
}

View File

@@ -9,6 +9,7 @@ import jodd.http.ProxyInfo;
import jodd.http.ProxyInfo.ProxyType;
import jodd.http.net.SSLSocketHttpConnectionProvider;
import jodd.http.net.SocketHttpConnectionProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
@@ -24,6 +25,7 @@ import java.util.Base64;
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Slf4j
public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl {
@Override
public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException {
@@ -31,13 +33,13 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl {
HttpRequest request = this.buildHttpRequest(url, requestStr, useKey);
byte[] responseBytes = request.send().bodyBytes();
final String responseString = Base64.getEncoder().encodeToString(responseBytes);
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据(Base64编码后)】:{}", url, requestStr, responseString);
log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据(Base64编码后)】:{}", url, requestStr, responseString);
if (this.getConfig().isIfSaveApiData()) {
wxApiData.set(new WxPayApiData(url, requestStr, responseString, null));
}
return responseBytes;
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage()));
throw new WxPayException(e.getMessage(), e);
}
@@ -49,13 +51,13 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl {
HttpRequest request = this.buildHttpRequest(url, requestStr, useKey);
String responseString = this.getResponseString(request.send());
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
if (this.getConfig().isIfSaveApiData()) {
wxApiData.set(new WxPayApiData(url, requestStr, responseString, null));
}
return responseString;
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage()));
throw new WxPayException(e.getMessage(), e);
}
@@ -146,9 +148,9 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl {
private String getResponseString(HttpResponse response) throws WxPayException {
try {
this.log.debug("【微信服务器响应头信息】:\n{}", response.toString(false));
log.debug("【微信服务器响应头信息】:\n{}", response.toString(false));
} catch (NullPointerException e) {
this.log.warn("HttpResponse.toString() 居然抛出空指针异常了", e);
log.warn("HttpResponse.toString() 居然抛出空指针异常了", e);
}
String responseString = response.bodyText();