mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 10:38:42 +08:00 
			
		
		
		
	#321 微信支付下载对账单接口增加对GZIP格式的支持
This commit is contained in:
		
							
								
								
									
										7
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								pom.xml
									
									
									
									
									
								
							| @ -225,6 +225,13 @@ | |||||||
|         <version>${jetty.version}</version> |         <version>${jetty.version}</version> | ||||||
|         <scope>test</scope> |         <scope>test</scope> | ||||||
|       </dependency> |       </dependency> | ||||||
|  |       <dependency> | ||||||
|  |         <groupId>org.assertj</groupId> | ||||||
|  |         <artifactId>assertj-guava</artifactId> | ||||||
|  |         <version>3.0.0</version> | ||||||
|  |         <scope>test</scope> | ||||||
|  |       </dependency> | ||||||
|  |  | ||||||
|       <dependency> |       <dependency> | ||||||
|         <groupId>redis.clients</groupId> |         <groupId>redis.clients</groupId> | ||||||
|         <artifactId>jedis</artifactId> |         <artifactId>jedis</artifactId> | ||||||
|  | |||||||
| @ -27,7 +27,6 @@ | |||||||
|     <dependency> |     <dependency> | ||||||
|       <groupId>org.jodd</groupId> |       <groupId>org.jodd</groupId> | ||||||
|       <artifactId>jodd-http</artifactId> |       <artifactId>jodd-http</artifactId> | ||||||
|       <scope>provided</scope> |  | ||||||
|     </dependency> |     </dependency> | ||||||
|  |  | ||||||
|     <dependency> |     <dependency> | ||||||
| @ -45,6 +44,11 @@ | |||||||
|       <artifactId>testng</artifactId> |       <artifactId>testng</artifactId> | ||||||
|       <scope>test</scope> |       <scope>test</scope> | ||||||
|     </dependency> |     </dependency> | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>org.assertj</groupId> | ||||||
|  |       <artifactId>assertj-guava</artifactId> | ||||||
|  |       <scope>test</scope> | ||||||
|  |     </dependency> | ||||||
|     <dependency> |     <dependency> | ||||||
|       <groupId>com.google.inject</groupId> |       <groupId>com.google.inject</groupId> | ||||||
|       <artifactId>guice</artifactId> |       <artifactId>guice</artifactId> | ||||||
|  | |||||||
| @ -36,7 +36,17 @@ public class WxPayConstants { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 订单类型 |    * 压缩账单的类型 | ||||||
|  |    */ | ||||||
|  |   public static class TarType { | ||||||
|  |     /** | ||||||
|  |      * 固定值:GZIP,返回格式为.gzip的压缩包账单 | ||||||
|  |      */ | ||||||
|  |     public static final String GZIP = "GZIP"; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 账单类型 | ||||||
|    */ |    */ | ||||||
|   public static class BillType { |   public static class BillType { | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -11,21 +11,47 @@ import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; | |||||||
| import com.github.binarywang.wxpay.bean.request.*; | import com.github.binarywang.wxpay.bean.request.*; | ||||||
| import com.github.binarywang.wxpay.bean.result.*; | import com.github.binarywang.wxpay.bean.result.*; | ||||||
| import com.github.binarywang.wxpay.config.WxPayConfig; | import com.github.binarywang.wxpay.config.WxPayConfig; | ||||||
|  | import com.github.binarywang.wxpay.constant.WxPayConstants; | ||||||
| import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; | import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; | ||||||
| import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | ||||||
| import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; | import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; | ||||||
| import com.github.binarywang.wxpay.exception.WxPayException; | import com.github.binarywang.wxpay.exception.WxPayException; | ||||||
| import com.github.binarywang.wxpay.service.WxPayService; | import com.github.binarywang.wxpay.service.WxPayService; | ||||||
| import com.github.binarywang.wxpay.util.SignUtils; | import com.github.binarywang.wxpay.util.SignUtils; | ||||||
|  | import com.google.common.base.Joiner; | ||||||
| import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||||
|  | import jodd.io.ZipUtil; | ||||||
|  | import jodd.util.Base64; | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
|  | 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.CloseableHttpResponse; | ||||||
|  | import org.apache.http.client.methods.HttpPost; | ||||||
|  | import org.apache.http.conn.ssl.DefaultHostnameVerifier; | ||||||
|  | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | ||||||
|  | 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 org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
|  | import javax.net.ssl.SSLContext; | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | import java.nio.file.Files; | ||||||
|  | import java.nio.file.Path; | ||||||
|  | import java.nio.file.Paths; | ||||||
| import java.util.*; | import java.util.*; | ||||||
|  | import java.util.zip.ZipException; | ||||||
|  |  | ||||||
| import static com.github.binarywang.wxpay.constant.WxPayConstants.QUERY_COMMENT_DATE_FORMAT; | import static com.github.binarywang.wxpay.constant.WxPayConstants.QUERY_COMMENT_DATE_FORMAT; | ||||||
|  | import static com.github.binarywang.wxpay.constant.WxPayConstants.TarType; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * <pre> |  * <pre> | ||||||
| @ -61,7 +87,17 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 发送post请求 |    * 发送post请求,得到响应字节数组 | ||||||
|  |    * | ||||||
|  |    * @param url        请求地址 | ||||||
|  |    * @param requestStr 请求信息 | ||||||
|  |    * @param useKey     是否使用证书 | ||||||
|  |    * @return 返回请求结果字节数组 | ||||||
|  |    */ | ||||||
|  |   protected abstract byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 发送post请求,得到响应字符串 | ||||||
|    * |    * | ||||||
|    * @param url        请求地址 |    * @param url        请求地址 | ||||||
|    * @param requestStr 请求信息 |    * @param requestStr 请求信息 | ||||||
| @ -410,6 +446,10 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public WxPayBillResult downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws WxPayException { |   public WxPayBillResult downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws WxPayException { | ||||||
|  |     if (!BillType.ALL.equals(billType)) { | ||||||
|  |       throw new WxPayException("目前仅支持ALL类型的对账单下载"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     WxPayDownloadBillRequest request = new WxPayDownloadBillRequest(); |     WxPayDownloadBillRequest request = new WxPayDownloadBillRequest(); | ||||||
|     request.setBillType(billType); |     request.setBillType(billType); | ||||||
|     request.setBillDate(billDate); |     request.setBillDate(billDate); | ||||||
| @ -419,15 +459,52 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService { | |||||||
|     request.checkAndSign(this.getConfig(), false); |     request.checkAndSign(this.getConfig(), false); | ||||||
|  |  | ||||||
|     String url = this.getPayBaseUrl() + "/pay/downloadbill"; |     String url = this.getPayBaseUrl() + "/pay/downloadbill"; | ||||||
|     String responseContent = this.post(url, request.toXML(), false); |  | ||||||
|     if (responseContent.startsWith("<")) { |     String responseContent; | ||||||
|       throw WxPayException.from(WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class)); |     if (TarType.GZIP.equals(tarType)) { | ||||||
|  |       responseContent = this.handleGzipBill(url, request.toXML()); | ||||||
|  |     } else { | ||||||
|  |       responseContent = this.post(url, request.toXML(), false); | ||||||
|  |       if (responseContent.startsWith("<")) { | ||||||
|  |         throw WxPayException.from(WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class)); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return this.handleBillInformation(responseContent); |     return this.handleBill(billType, responseContent); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private WxPayBillResult handleBillInformation(String responseContent) { |   private WxPayBillResult handleBill(String billType, String responseContent) { | ||||||
|  |     if (!BillType.ALL.equals(billType)) { | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return this.handleAllBill(responseContent); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private String handleGzipBill(String url, String requestStr) throws WxPayException { | ||||||
|  |     try { | ||||||
|  |       byte[] responseBytes = this.postForBytes(url, requestStr, false); | ||||||
|  |       Path tempDirectory = Files.createTempDirectory("bill"); | ||||||
|  |       Path path = Paths.get(tempDirectory.toString(), System.currentTimeMillis() + ".gzip"); | ||||||
|  |       Files.write(path, responseBytes); | ||||||
|  |       try { | ||||||
|  |         List<String> allLines = Files.readAllLines(ZipUtil.ungzip(path.toFile()).toPath(), StandardCharsets.UTF_8); | ||||||
|  |         return Joiner.on("\n").join(allLines); | ||||||
|  |       } catch (ZipException e) { | ||||||
|  |         if (e.getMessage().contains("Not in GZIP format")) { | ||||||
|  |           throw WxPayException.from(WxPayBaseResult.fromXML(new String(responseBytes, StandardCharsets.UTF_8), | ||||||
|  |             WxPayCommonResult.class)); | ||||||
|  |         } else { | ||||||
|  |           this.log.error("解压zip文件出错", e); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }   catch (IOException e) { | ||||||
|  |       e.printStackTrace(); | ||||||
|  |     } | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private WxPayBillResult handleAllBill(String responseContent) { | ||||||
|     WxPayBillResult wxPayBillResult = new WxPayBillResult(); |     WxPayBillResult wxPayBillResult = new WxPayBillResult(); | ||||||
|  |  | ||||||
|     String listStr = ""; |     String listStr = ""; | ||||||
| @ -444,11 +521,16 @@ public abstract class WxPayServiceAbstractImpl implements WxPayService { | |||||||
|      * 参考以上格式进行取值 |      * 参考以上格式进行取值 | ||||||
|      */ |      */ | ||||||
|     List<WxPayBillBaseResult> wxPayBillBaseResultLst = new LinkedList<>(); |     List<WxPayBillBaseResult> wxPayBillBaseResultLst = new LinkedList<>(); | ||||||
|     String newStr = listStr.replaceAll(",", " "); // 去空格 |     // 去空格 | ||||||
|     String[] tempStr = newStr.split("`"); // 数据分组 |     String newStr = listStr.replaceAll(",", " "); | ||||||
|     String[] t = tempStr[0].split(" ");// 分组标题 |     // 数据分组 | ||||||
|     int j = tempStr.length / t.length; // 计算循环次数 |     String[] tempStr = newStr.split("`"); | ||||||
|     int k = 1; // 纪录数组下标 |     // 分组标题 | ||||||
|  |     String[] t = tempStr[0].split(" "); | ||||||
|  |     // 计算循环次数 | ||||||
|  |     int j = tempStr.length / t.length; | ||||||
|  |     // 纪录数组下标 | ||||||
|  |     int k = 1; | ||||||
|     for (int i = 0; i < j; i++) { |     for (int i = 0; i < j; i++) { | ||||||
|       WxPayBillBaseResult wxPayBillBaseResult = new WxPayBillBaseResult(); |       WxPayBillBaseResult wxPayBillBaseResult = new WxPayBillBaseResult(); | ||||||
|  |  | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package com.github.binarywang.wxpay.service.impl; | |||||||
|  |  | ||||||
| import com.github.binarywang.wxpay.bean.WxPayApiData; | import com.github.binarywang.wxpay.bean.WxPayApiData; | ||||||
| import com.github.binarywang.wxpay.exception.WxPayException; | import com.github.binarywang.wxpay.exception.WxPayException; | ||||||
|  | import jodd.util.Base64; | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
| import org.apache.http.auth.AuthScope; | import org.apache.http.auth.AuthScope; | ||||||
| import org.apache.http.auth.UsernamePasswordCredentials; | import org.apache.http.auth.UsernamePasswordCredentials; | ||||||
| @ -19,11 +20,12 @@ import org.apache.http.impl.client.HttpClients; | |||||||
| import org.apache.http.util.EntityUtils; | import org.apache.http.util.EntityUtils; | ||||||
|  |  | ||||||
| import javax.net.ssl.SSLContext; | import javax.net.ssl.SSLContext; | ||||||
|  | import java.io.UnsupportedEncodingException; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * <pre> |  * <pre> | ||||||
|  * 微信支付请求实现类,apache httpclient实现 |  * 微信支付请求实现类,apache httpclient实现. | ||||||
|  * Created by Binary Wang on 2016/7/28. |  * Created by Binary Wang on 2016/7/28. | ||||||
|  * </pre> |  * </pre> | ||||||
|  * |  * | ||||||
| @ -31,41 +33,35 @@ import java.nio.charset.StandardCharsets; | |||||||
|  */ |  */ | ||||||
| public class WxPayServiceApacheHttpImpl extends WxPayServiceAbstractImpl { | public class WxPayServiceApacheHttpImpl extends WxPayServiceAbstractImpl { | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   protected 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.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 |   @Override | ||||||
|   protected String post(String url, String requestStr, boolean useKey) throws WxPayException { |   protected String post(String url, String requestStr, boolean useKey) throws WxPayException { | ||||||
|     try { |     try { | ||||||
|       HttpClientBuilder httpClientBuilder = HttpClients.custom(); |       HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey); | ||||||
|       if (useKey) { |       HttpPost httpPost = this.createHttpPost(url, requestStr); | ||||||
|         SSLContext sslContext = this.getConfig().getSslContext(); |  | ||||||
|         if (null == sslContext) { |  | ||||||
|           sslContext = this.getConfig().initSSLContext(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, |  | ||||||
|           new String[]{"TLSv1"}, null, new DefaultHostnameVerifier()); |  | ||||||
|         httpClientBuilder.setSSLSocketFactory(sslsf); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       HttpPost httpPost = new HttpPost(url); |  | ||||||
|  |  | ||||||
|       httpPost.setConfig(RequestConfig.custom() |  | ||||||
|         .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) |  | ||||||
|         .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) |  | ||||||
|         .setSocketTimeout(this.getConfig().getHttpTimeout()) |  | ||||||
|         .build()); |  | ||||||
|  |  | ||||||
|       if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) |  | ||||||
|         && this.getConfig().getHttpProxyPort() > 0) { |  | ||||||
|         // 使用代理服务器 需要用户认证的代理服务器 |  | ||||||
|         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); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       try (CloseableHttpClient httpclient = httpClientBuilder.build()) { |       try (CloseableHttpClient httpclient = httpClientBuilder.build()) { | ||||||
|         httpPost.setEntity(new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1))); |  | ||||||
|         try (CloseableHttpResponse response = httpclient.execute(httpPost)) { |         try (CloseableHttpResponse response = httpclient.execute(httpPost)) { | ||||||
|           String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); |           String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); | ||||||
|           this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); |           this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); | ||||||
| @ -82,4 +78,56 @@ public class WxPayServiceApacheHttpImpl extends WxPayServiceAbstractImpl { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private StringEntity createEntry(String requestStr) { | ||||||
|  |     try { | ||||||
|  |       return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); | ||||||
|  |     } catch (UnsupportedEncodingException e) { | ||||||
|  |       //cannot happen | ||||||
|  |       this.log.error(e.getMessage(),e); | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private HttpClientBuilder createHttpClientBuilder(boolean useKey) throws WxPayException { | ||||||
|  |     HttpClientBuilder httpClientBuilder = HttpClients.custom(); | ||||||
|  |     if (useKey) { | ||||||
|  |       this.setKey(httpClientBuilder); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) | ||||||
|  |       && this.getConfig().getHttpProxyPort() > 0) { | ||||||
|  |       // 使用代理服务器 需要用户认证的代理服务器 | ||||||
|  |       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); | ||||||
|  |     } | ||||||
|  |     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 setKey(HttpClientBuilder httpClientBuilder) throws WxPayException { | ||||||
|  |     SSLContext sslContext = this.getConfig().getSslContext(); | ||||||
|  |     if (null == sslContext) { | ||||||
|  |       sslContext = this.getConfig().initSSLContext(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, | ||||||
|  |       new String[]{"TLSv1"}, null, new DefaultHostnameVerifier()); | ||||||
|  |     httpClientBuilder.setSSLSocketFactory(sslsf); | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,48 +9,40 @@ import jodd.http.ProxyInfo; | |||||||
| import jodd.http.ProxyInfo.ProxyType; | import jodd.http.ProxyInfo.ProxyType; | ||||||
| import jodd.http.net.SSLSocketHttpConnectionProvider; | import jodd.http.net.SSLSocketHttpConnectionProvider; | ||||||
| import jodd.http.net.SocketHttpConnectionProvider; | import jodd.http.net.SocketHttpConnectionProvider; | ||||||
|  | import jodd.util.Base64; | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
|  |  | ||||||
| import javax.net.ssl.SSLContext; | import javax.net.ssl.SSLContext; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 微信支付请求实现类,jodd-http实现 |  * 微信支付请求实现类,jodd-http实现. | ||||||
|  * Created by Binary Wang on 2016/7/28. |  * Created by Binary Wang on 2016/7/28. | ||||||
|  * |  * | ||||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> |  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||||
|  */ |  */ | ||||||
| public class WxPayServiceJoddHttpImpl extends WxPayServiceAbstractImpl { | public class WxPayServiceJoddHttpImpl extends WxPayServiceAbstractImpl { | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   protected byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { | ||||||
|  |     try { | ||||||
|  |       HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); | ||||||
|  |       byte[] responseBytes = request.send().bodyBytes(); | ||||||
|  |       final String responseString = Base64.encodeToString(responseBytes); | ||||||
|  |       this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据(Base64编码后)】:{}", url, requestStr, responseString); | ||||||
|  |       wxApiData.set(new WxPayApiData(url, requestStr, responseString, null)); | ||||||
|  |       return responseBytes; | ||||||
|  |     } 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 |   @Override | ||||||
|   protected String post(String url, String requestStr, boolean useKey) throws WxPayException { |   protected String post(String url, String requestStr, boolean useKey) throws WxPayException { | ||||||
|     try { |     try { | ||||||
|       HttpRequest request = HttpRequest |       HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); | ||||||
|         .post(url) |  | ||||||
|         .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) { |  | ||||||
|         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); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       String responseString = this.getResponseString(request.send()); |       String responseString = this.getResponseString(request.send()); | ||||||
|  |  | ||||||
|       this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); |       this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); | ||||||
| @ -63,6 +55,35 @@ public class WxPayServiceJoddHttpImpl extends WxPayServiceAbstractImpl { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private HttpRequest buildHttpRequest(String url, String requestStr, boolean useKey) throws WxPayException { | ||||||
|  |     HttpRequest request = HttpRequest | ||||||
|  |       .post(url) | ||||||
|  |       .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) { | ||||||
|  |       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 { |   private String getResponseString(HttpResponse response) throws WxPayException { | ||||||
|     try { |     try { | ||||||
|       this.log.debug("【微信服务器响应头信息】:\n{}", response.toString(false)); |       this.log.debug("【微信服务器响应头信息】:\n{}", response.toString(false)); | ||||||
|  | |||||||
| @ -26,6 +26,8 @@ import java.nio.file.Path; | |||||||
| import java.util.Calendar; | import java.util.Calendar; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
|  |  | ||||||
|  | import static com.github.binarywang.wxpay.constant.WxPayConstants.*; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.testng.Assert.*; | import static org.testng.Assert.*; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -139,7 +141,13 @@ public class WxPayServiceAbstractImplTest { | |||||||
|   @DataProvider |   @DataProvider | ||||||
|   public Object[][] billingData() { |   public Object[][] billingData() { | ||||||
|     return new Object[][]{ |     return new Object[][]{ | ||||||
| //      {"20170831", BillType.ALL, null, "deviceInfo"}, |       {"20170831", BillType.ALL, TarType.GZIP, "deviceInfo"}, | ||||||
|  |       {"20170831", BillType.RECHARGE_REFUND, TarType.GZIP, "deviceInfo"}, | ||||||
|  |       {"20170831", BillType.REFUND, TarType.GZIP, "deviceInfo"}, | ||||||
|  |       {"20170831", BillType.SUCCESS, TarType.GZIP, "deviceInfo"}, | ||||||
|  |       {"20170831", BillType.ALL, null, "deviceInfo"}, | ||||||
|  |       {"20170831", BillType.RECHARGE_REFUND, null, "deviceInfo"}, | ||||||
|  |       {"20170831", BillType.REFUND, null, "deviceInfo"}, | ||||||
|       {"20170831", BillType.SUCCESS, null, "deviceInfo"} |       {"20170831", BillType.SUCCESS, null, "deviceInfo"} | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| @ -148,11 +156,11 @@ public class WxPayServiceAbstractImplTest { | |||||||
|   public void testDownloadBill(String billDate, String billType, |   public void testDownloadBill(String billDate, String billType, | ||||||
|                                String tarType, String deviceInfo) throws Exception { |                                String tarType, String deviceInfo) throws Exception { | ||||||
|     WxPayBillResult billResult = this.payService.downloadBill(billDate, billType, tarType, deviceInfo); |     WxPayBillResult billResult = this.payService.downloadBill(billDate, billType, tarType, deviceInfo); | ||||||
|     assertNotNull(billResult); |     assertThat(billResult).isNotNull(); | ||||||
|     this.logger.info(billResult.toString()); |     this.logger.info(billResult.toString()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test(expectedExceptions = WxPayException.class) | ||||||
|   public void testDownloadBill_withNoParams() throws Exception { |   public void testDownloadBill_withNoParams() throws Exception { | ||||||
|     //必填字段为空时,抛出异常 |     //必填字段为空时,抛出异常 | ||||||
|     this.payService.downloadBill("", "", "", null); |     this.payService.downloadBill("", "", "", null); | ||||||
| @ -247,7 +255,7 @@ public class WxPayServiceAbstractImplTest { | |||||||
|       .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") |       .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") | ||||||
|       .amount(1) |       .amount(1) | ||||||
|       .spbillCreateIp("10.10.10.10") |       .spbillCreateIp("10.10.10.10") | ||||||
|       .checkName(WxPayConstants.CheckNameOption.NO_CHECK) |       .checkName(CheckNameOption.NO_CHECK) | ||||||
|       .description("描述信息") |       .description("描述信息") | ||||||
|       .build(); |       .build(); | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Binary Wang
					Binary Wang