From b26c7867979ee1c9d3eebabd5c6babae6796d499 Mon Sep 17 00:00:00 2001 From: accept mediocrity <165350377+AcceptMediocrity@users.noreply.github.com> Date: Tue, 28 Oct 2025 11:51:26 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20#3745=20=E3=80=90=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E3=80=91=E4=BF=AE=E5=A4=8D=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E4=BB=BF=E7=9C=9F=E6=B5=8B=E8=AF=95=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=97=B6=E9=AA=8C=E7=AD=BE=E5=AF=86=E9=92=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E7=9A=84=20Content-Type=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/service/WxPayService.java | 14 +++++ .../service/impl/BaseWxPayServiceImpl.java | 3 +- .../impl/WxPayServiceApacheHttpImpl.java | 47 ++++++++++++++++- .../impl/WxPayServiceHttpComponentsImpl.java | 44 ++++++++++++++++ .../impl/WxPayServiceJoddHttpImpl.java | 52 +++++++++++++++++++ 5 files changed, 157 insertions(+), 3 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index c73fb843e..4ee5226d3 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -109,6 +109,19 @@ public interface WxPayService { */ String post(String url, String requestStr, boolean useKey) throws WxPayException; + + /** + * 发送post请求,得到响应字符串. + * + * @param url 请求地址 + * @param requestStr 请求信息 + * @param useKey 是否使用证书 + * @param mimeType Content-Type请求头 + * @return 返回请求结果字符串 string + * @throws WxPayException the wx pay exception + */ + String post(String url, String requestStr, boolean useKey, String mimeType) throws WxPayException; + /** * 发送post请求,得到响应字符串. * @@ -1457,6 +1470,7 @@ public interface WxPayService { * 是否需要证书: 否 * 请求方式: POST * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1 + * 注意: 微信暂不支持api v3 * * * @return the sandbox sign key diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index f32083a63..3884881b8 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -35,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxRuntimeException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.ConstructorUtils; +import org.apache.http.entity.ContentType; import java.io.File; import java.io.IOException; @@ -1262,7 +1263,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { request.checkAndSign(this.getConfig()); String url = "https://api.mch.weixin.qq.com/xdc/apiv2getsignkey/sign/getsignkey"; - String responseContent = this.post(url, request.toXML(), false); + String responseContent = this.post(url, request.toXML(), false, ContentType.APPLICATION_XML.getMimeType()); WxPaySandboxSignKeyResult result = BaseWxPayResult.fromXML(responseContent, WxPaySandboxSignKeyResult.class); result.checkResult(this, request.getSignType(), true); return result.getSandboxSignKey(); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java index 977a2856f..96454e5c0 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java @@ -54,7 +54,7 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { try { HttpPost httpPost = this.createHttpPost(url, requestStr); CloseableHttpClient httpClient = this.createHttpClient(useKey); - + // 使用连接池的客户端,不需要手动关闭 final byte[] bytes = httpClient.execute(httpPost, ByteArrayResponseHandler.INSTANCE); final String responseData = Base64.getEncoder().encodeToString(bytes); @@ -73,7 +73,33 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { try { HttpPost httpPost = this.createHttpPost(url, requestStr); CloseableHttpClient httpClient = this.createHttpClient(useKey); - + + // 使用连接池的客户端,不需要手动关闭 + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + this.logRequestAndResponse(url, requestStr, responseString); + if (this.getConfig().isIfSaveApiData()) { + wxApiData.set(new WxPayApiData(url, requestStr, responseString, null)); + } + return responseString; + } finally { + httpPost.releaseConnection(); + } + } catch (Exception e) { + this.logError(url, requestStr, e); + if (this.getConfig().isIfSaveApiData()) { + wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage())); + } + throw new WxPayException(e.getMessage(), e); + } + } + + @Override + public String post(String url, String requestStr, boolean useKey, String mimeType) throws WxPayException { + try { + HttpPost httpPost = this.createHttpPost(url, requestStr, mimeType); + CloseableHttpClient httpClient = this.createHttpClient(useKey); + // 使用连接池的客户端,不需要手动关闭 try (CloseableHttpResponse response = httpClient.execute(httpPost)) { String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); @@ -306,6 +332,10 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { //return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); } + private static StringEntity createEntry(String requestStr, String mimeType) { + return new StringEntity(requestStr, ContentType.create(mimeType, StandardCharsets.UTF_8)); + //return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); + } private HttpClientBuilder createHttpClientBuilder(boolean useKey) throws WxPayException { HttpClientBuilder httpClientBuilder = HttpClients.custom(); if (useKey) { @@ -348,6 +378,19 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { return httpPost; } + private HttpPost createHttpPost(String url, String requestStr, String mimeType) throws WxPayException { + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(createEntry(requestStr, mimeType)); + + httpPost.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) + .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) + .setSocketTimeout(this.getConfig().getHttpTimeout()) + .build()); + + return httpPost; + } + private void initSSLContext(HttpClientBuilder httpClientBuilder) throws WxPayException { SSLContext sslContext = this.getConfig().getSslContext(); if (null == sslContext) { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java index 1c558f711..5c21a06a8 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceHttpComponentsImpl.java @@ -91,6 +91,32 @@ public class WxPayServiceHttpComponentsImpl extends BaseWxPayServiceImpl { } } + @Override + public String post(String url, String requestStr, boolean useKey, String mimeType) throws WxPayException { + try { + HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey); + HttpPost httpPost = this.createHttpPost(url, requestStr, mimeType); + try (CloseableHttpClient httpClient = httpClientBuilder.build()) { + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + this.logRequestAndResponse(url, requestStr, responseString); + if (this.getConfig().isIfSaveApiData()) { + wxApiData.set(new WxPayApiData(url, requestStr, responseString, null)); + } + return responseString; + } + } finally { + httpPost.releaseConnection(); + } + } catch (Exception e) { + this.logError(url, requestStr, e); + if (this.getConfig().isIfSaveApiData()) { + wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage())); + } + throw new WxPayException(e.getMessage(), e); + } + } + @Override public String postV3(String url, String requestStr) throws WxPayException { HttpPost httpPost = this.createHttpPost(url, requestStr); @@ -283,6 +309,11 @@ public class WxPayServiceHttpComponentsImpl extends BaseWxPayServiceImpl { //return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); } + private static StringEntity createEntry(String requestStr, String mimeType) { + return new StringEntity(requestStr, ContentType.create(mimeType, StandardCharsets.UTF_8)); + //return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); + } + private HttpClientBuilder createHttpClientBuilder(boolean useKey) throws WxPayException { HttpClientBuilder httpClientBuilder = HttpClients.custom(); if (useKey) { @@ -325,6 +356,19 @@ public class WxPayServiceHttpComponentsImpl extends BaseWxPayServiceImpl { return httpPost; } + private HttpPost createHttpPost(String url, String requestStr, String mimeType) throws WxPayException { + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(createEntry(requestStr, mimeType)); + + httpPost.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) + .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) + .setSocketTimeout(this.getConfig().getHttpTimeout()) + .build()); + + return httpPost; + } + private void initSSLContext(HttpClientBuilder httpClientBuilder) throws WxPayException { SSLContext sslContext = this.getConfig().getSslContext(); if (null == sslContext) { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java index 7c2f1e82c..6c8bcec89 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java @@ -63,6 +63,24 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl { } } + @Override + public String post(String url, String requestStr, boolean useKey, String mimeType) throws WxPayException { + try { + HttpRequest request = this.buildHttpRequest(url, requestStr, useKey, mimeType); + String responseString = this.getResponseString(request.send()); + + 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) { + log.error("\n【请求地址】:{}\n【请求数据】:{}\n【异常信息】:{}", url, requestStr, e.getMessage()); + wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage())); + throw new WxPayException(e.getMessage(), e); + } + } + @Override public String postV3(String url, String requestStr) throws WxPayException { return null; @@ -146,6 +164,40 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl { return request; } + private HttpRequest buildHttpRequest(String url, String requestStr, boolean useKey, String mimeType) throws WxPayException { + HttpRequest request = HttpRequest + .post(url) + .contentType(mimeType) + .timeout(this.getConfig().getHttpTimeout()) + .connectionTimeout(this.getConfig().getHttpConnectionTimeout()) + .bodyText(requestStr); + + if (useKey) { + SSLContext sslContext = this.getConfig().getSslContext(); + if (null == sslContext) { + sslContext = this.getConfig().initSSLContext(); + } + final SSLSocketHttpConnectionProvider provider = new SSLSocketHttpConnectionProvider(sslContext); + request.withConnectionProvider(provider); + } + + if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { + if (StringUtils.isEmpty(this.getConfig().getHttpProxyUsername())) { + this.getConfig().setHttpProxyUsername("whatever"); + } + + ProxyInfo httpProxy = new ProxyInfo(ProxyType.HTTP, this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort(), + this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword()); + HttpConnectionProvider provider = request.connectionProvider(); + if (null == provider) { + provider = new SocketHttpConnectionProvider(); + } + provider.useProxy(httpProxy); + request.withConnectionProvider(provider); + } + return request; + } + private String getResponseString(HttpResponse response) throws WxPayException { try { log.debug("【微信服务器响应头信息】:\n{}", response.toString(false));