All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.binarywang.wxpay.service.impl.WxPayServiceApacheHttpImpl Maven / Gradle / Ivy

The newest version!
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.WxPayApiData;
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 me.chanjar.weixin.common.util.json.GsonParser;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;
import java.util.Optional;

/**
 * 
 * 微信支付请求实现类,apache httpclient实现.
 * Created by Binary Wang on 2016/7/28.
 * 
* * @author Binary Wang */ 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"; @Override public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { try { HttpClientBuilder httpClientBuilder = createHttpClientBuilder(useKey); HttpPost httpPost = this.createHttpPost(url, requestStr); try (CloseableHttpClient httpClient = httpClientBuilder.build()) { 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); wxApiData.set(new WxPayApiData(url, requestStr, responseData, null)); return bytes; } } finally { httpPost.releaseConnection(); } } catch (Exception e) { this.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 post(String url, String requestStr, boolean useKey) throws WxPayException { try { HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey); HttpPost httpPost = this.createHttpPost(url, requestStr); 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); if (this.getConfig().isIfSaveApiData()) { wxApiData.set(new WxPayApiData(url, requestStr, responseString, null)); } return responseString; } } finally { httpPost.releaseConnection(); } } catch (Exception e) { this.log.error("\n【请求地址】:{}\n【请求数据】:{}\n【异常信息】:{}", url, requestStr, e.getMessage()); 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 { CloseableHttpClient httpClient = this.createApiV3HttpClient(); HttpPost httpPost = this.createHttpPost(url, requestStr); httpPost.addHeader(ACCEPT, APPLICATION_JSON); httpPost.addHeader(CONTENT_TYPE, APPLICATION_JSON); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { //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 { httpPost.releaseConnection(); } } @Override public String patchV3(String url, String requestStr) throws WxPayException { CloseableHttpClient httpClient = this.createApiV3HttpClient(); HttpPatch httpPatch = new HttpPatch(url); 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(); } } @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 = getConfig().getVerifier().getValidCertificate().getSerialNumber().toString(16).toUpperCase(); httpPost.addHeader("Wechatpay-Serial", serialNumber); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { //v3已经改为通过状态码判断200 204 成功 int statusCode = response.getStatusLine().getStatusCode(); String responseString = "{}"; HttpEntity entity = response.getEntity(); if (entity != null) { responseString = EntityUtils.toString(entity, 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()); e.printStackTrace(); throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e); } finally { httpPost.releaseConnection(); } } @Override public String postV3(String url, HttpPost httpPost) throws WxPayException { 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()); CloseableHttpClient httpClient = this.createApiV3HttpClient(); try (CloseableHttpResponse response = httpClient.execute(httpRequest)) { //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【响应数据】:{}", url, responseString); return responseString; } //有错误提示信息返回 JsonObject jsonObject = GsonParser.parse(responseString); throw convertException(jsonObject); } catch (Exception e) { this.log.error("\n【请求地址】:{}\n【异常信息】:{}", url, e.getMessage()); throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e); } finally { httpRequest.releaseConnection(); } } @Override public String getV3(String url) throws WxPayException { HttpGet httpGet = new HttpGet(url); httpGet.addHeader(ACCEPT, APPLICATION_JSON); httpGet.addHeader(CONTENT_TYPE, APPLICATION_JSON); 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 = getConfig().getVerifier().getValidCertificate().getSerialNumber().toString(16).toUpperCase(); 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()); try (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); return response.getEntity().getContent(); } //response里的header有content-type=json说明返回了错误信息 //有错误提示信息返回 String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); JsonObject jsonObject = GsonParser.parse(responseString); throw convertException(jsonObject); } catch (Exception e) { this.log.error("\n【请求地址】:{}\n【异常信息】:{}", url, e.getMessage()); throw (e instanceof WxPayException) ? (WxPayException) e : new WxPayException(e.getMessage(), e); } finally { httpGet.releaseConnection(); } } @Override public String putV3(String url, String requestStr) throws WxPayException { HttpPut httpPut = new HttpPut(url); StringEntity entity = this.createEntry(requestStr); httpPut.setEntity(entity); httpPut.addHeader(ACCEPT, APPLICATION_JSON); httpPut.addHeader(CONTENT_TYPE, APPLICATION_JSON); 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); return requestV3(url, httpDelete); } private CloseableHttpClient createApiV3HttpClient() throws WxPayException { CloseableHttpClient apiV3HttpClient = this.getConfig().getApiV3HttpClient(); if (null == apiV3HttpClient) { return this.getConfig().initApiV3HttpClient(); } return apiV3HttpClient; } private StringEntity createEntry(String requestStr) { return new StringEntity(requestStr, ContentType.create(APPLICATION_JSON, "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) { this.initSSLContext(httpClientBuilder); } if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { if (StringUtils.isEmpty(this.getConfig().getHttpProxyUsername())) { this.getConfig().setHttpProxyUsername("whatever"); } // 使用代理服务器 需要用户认证的代理服务器 CredentialsProvider provider = new BasicCredentialsProvider(); provider.setCredentials(new AuthScope(this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort()), new UsernamePasswordCredentials(this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword())); httpClientBuilder.setDefaultCredentialsProvider(provider) .setProxy(new HttpHost(this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort())); } // 提供自定义httpClientBuilder的能力 Optional.ofNullable(getConfig().getHttpClientBuilderCustomizer()).ifPresent(e -> { e.customize(httpClientBuilder); }); return httpClientBuilder; } private HttpPost createHttpPost(String url, String requestStr) { HttpPost httpPost = new HttpPost(url); httpPost.setEntity(this.createEntry(requestStr)); 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) { sslContext = this.getConfig().initSSLContext(); } httpClientBuilder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, new DefaultHostnameVerifier())); } private WxPayException convertException(JsonObject jsonObject) { //todo 这里考虑使用新的适用于V3的异常 JsonElement codeElement = jsonObject.get("code"); String code = codeElement == null ? null : codeElement.getAsString(); String message = jsonObject.get("message").getAsString(); WxPayException wxPayException = new WxPayException(message); wxPayException.setErrCode(code); wxPayException.setErrCodeDes(message); return wxPayException; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy