mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-11-01 03:25:35 +08:00 
			
		
		
		
	在原来的基础上创建更简洁的调用红包接口,请在这之前初始化配置中的SslContext,新增SslContext的get|set方法,方便spring注入
This commit is contained in:
		| @ -118,7 +118,20 @@ public interface WxMpConfigStorage { | ||||
|  | ||||
|   File getTmpDirFile(); | ||||
|  | ||||
|   @Deprecated | ||||
|   SSLContext getSSLContext(); | ||||
|    | ||||
|   SSLContext getSslContext(); | ||||
|    | ||||
|   void setSslContext(SSLContext sslContext); | ||||
|    | ||||
| 	/** | ||||
| 	 * 在此之前,必须将partnerId进行赋值 | ||||
| 	 *  | ||||
| 	 * @param filePath | ||||
| 	 *          apiclient_cert.p12的文件的绝对路径 | ||||
| 	 */ | ||||
| 	void setSslContextFilePath(String filePath) throws Exception; | ||||
|  | ||||
|   /** | ||||
|    * http client builder | ||||
|  | ||||
| @ -1,14 +1,19 @@ | ||||
| package me.chanjar.weixin.mp.api; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.security.KeyStore; | ||||
| import java.util.concurrent.locks.Lock; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
|  | ||||
| import javax.net.ssl.SSLContext; | ||||
|  | ||||
| import org.apache.http.ssl.SSLContexts; | ||||
|  | ||||
| import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
| import me.chanjar.weixin.common.util.ToStringUtils; | ||||
| import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | ||||
|  | ||||
| import javax.net.ssl.SSLContext; | ||||
| import java.io.File; | ||||
| import java.util.concurrent.locks.Lock; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
|  | ||||
| /** | ||||
|  * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | ||||
|  * @author chanjarster | ||||
| @ -300,11 +305,33 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | ||||
|   public SSLContext getSSLContext() { | ||||
|     return this.sslContext; | ||||
|   } | ||||
|  | ||||
|   public void setSSLContext(SSLContext context) { | ||||
|     this.sslContext = context; | ||||
|    | ||||
|   @Override | ||||
|   public SSLContext getSslContext() { | ||||
|   	return this.sslContext; | ||||
|   } | ||||
|  | ||||
| 	@Override | ||||
| 	public void setSslContextFilePath(String filePath) throws Exception { | ||||
| 		if (null == partnerId) { | ||||
| 			throw new Exception("请先将partnerId进行赋值"); | ||||
| 		} | ||||
| 			File file = new File(filePath); | ||||
| 			if (!file.exists()) { | ||||
| 				throw new RuntimeException(file.getPath() + ":文件不存在!在设置SSLContext的时候"); | ||||
| 			} | ||||
| 			FileInputStream inputStream = new FileInputStream(file); | ||||
| 			KeyStore keystore = KeyStore.getInstance("PKCS12"); | ||||
| 			char[] partnerId2charArray = partnerId.toCharArray(); | ||||
| 			keystore.load(inputStream, partnerId2charArray); | ||||
| 			this.sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setSslContext(SSLContext context) { | ||||
| 		this.sslContext = context; | ||||
| 	} | ||||
|    | ||||
|   @Override | ||||
|   public ApacheHttpClientBuilder getApacheHttpClientBuilder() { | ||||
|     return this.apacheHttpClientBuilder; | ||||
|  | ||||
| @ -197,8 +197,24 @@ public interface WxMpPayService { | ||||
|    * @param request 请求对象 | ||||
|    * @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | ||||
|    */ | ||||
|   @Deprecated | ||||
|   WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 发送微信红包给个人用户 | ||||
|    * <pre> | ||||
|    * 文档详见: | ||||
|    * 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3 | ||||
|    *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack | ||||
|    * 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4 | ||||
|    *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param request 请求对象 | ||||
|    * @param keyFile 证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | ||||
|    */ | ||||
|   WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxErrorException; | ||||
|   | ||||
|   /** | ||||
|    * <pre> | ||||
|    *   查询红包记录 | ||||
| @ -211,7 +227,22 @@ public interface WxMpPayService { | ||||
|    * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 | ||||
|    * @param keyFile   证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | ||||
|    */ | ||||
|   @Deprecated | ||||
|   WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException; | ||||
|    | ||||
|   /** | ||||
|    * <pre> | ||||
|    *   查询红包记录 | ||||
|    *   用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。 | ||||
|    *   请求Url	https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo | ||||
|    *   是否需要证书	是(证书及使用说明详见商户证书) | ||||
|    *   请求方式	POST | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 | ||||
|    * @param keyFile   证书文件对象(即apiclient_cert.p12 商户证书文件,详细参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3) | ||||
|    */ | ||||
|   WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * <pre> | ||||
|  | ||||
| @ -160,6 +160,7 @@ public class WxMpPayServiceImpl implements WxMpPayService { | ||||
|  | ||||
|  | ||||
|   @Override | ||||
|   @Deprecated | ||||
|   public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request, File keyFile) | ||||
|     throws WxErrorException { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
| @ -179,8 +180,30 @@ public class WxMpPayServiceImpl implements WxMpPayService { | ||||
|     this.checkResult(result); | ||||
|     return result; | ||||
|   } | ||||
|    | ||||
|   @Override | ||||
|   public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) | ||||
|   		throws WxErrorException { | ||||
|   	XStream xstream = XStreamInitializer.getInstance(); | ||||
|   	xstream.processAnnotations(WxPaySendRedpackRequest.class); | ||||
|   	xstream.processAnnotations(WxPaySendRedpackResult.class); | ||||
|   	 | ||||
|   	initRequest(request); | ||||
|   	request.setSign(this.createSign(request)); | ||||
|   	 | ||||
|   	String url = PAY_BASE_URL + "/mmpaymkttransfers/sendredpack"; | ||||
|   	if (request.getAmtType() != null) { | ||||
|   		//裂变红包 | ||||
|   		url = PAY_BASE_URL + "/mmpaymkttransfers/sendgroupredpack"; | ||||
|   	} | ||||
|   	String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | ||||
|   	WxPaySendRedpackResult result = (WxPaySendRedpackResult) xstream.fromXML(responseContent); | ||||
|   	this.checkResult(result); | ||||
|   	return result; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   @Deprecated | ||||
|   public WxPayRedpackQueryResult queryRedpack(String mchBillNo, File keyFile) throws WxErrorException { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|     xstream.processAnnotations(WxPayRedpackQueryRequest.class); | ||||
| @ -198,6 +221,25 @@ public class WxMpPayServiceImpl implements WxMpPayService { | ||||
|     this.checkResult(result); | ||||
|     return result; | ||||
|   } | ||||
|    | ||||
|   @Override | ||||
|   public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxErrorException { | ||||
|   	XStream xstream = XStreamInitializer.getInstance(); | ||||
|   	xstream.processAnnotations(WxPayRedpackQueryRequest.class); | ||||
|   	xstream.processAnnotations(WxPayRedpackQueryResult.class); | ||||
|   	 | ||||
|   	WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); | ||||
|   	request.setMchBillNo(mchBillNo); | ||||
|   	request.setBillType("MCHT"); | ||||
|   	initRequest(request); | ||||
|   	request.setSign(this.createSign(request)); | ||||
|   	 | ||||
|   	String url = PAY_BASE_URL + "/mmpaymkttransfers/gethbinfo"; | ||||
|   	String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request)); | ||||
|   	WxPayRedpackQueryResult result = (WxPayRedpackQueryResult) xstream.fromXML(responseContent); | ||||
|   	this.checkResult(result); | ||||
|   	return result; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxErrorException { | ||||
| @ -383,7 +425,8 @@ public class WxMpPayServiceImpl implements WxMpPayService { | ||||
|       httpPost.releaseConnection(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|    | ||||
|   @Deprecated | ||||
|   private String executeRequestWithKeyFile(String url, File keyFile, String requestStr, String mchId) throws WxErrorException { | ||||
|     try (FileInputStream inputStream = new FileInputStream(keyFile)) { | ||||
|       KeyStore keyStore = KeyStore.getInstance("PKCS12"); | ||||
| @ -414,6 +457,37 @@ public class WxMpPayServiceImpl implements WxMpPayService { | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   private String executeRequestWithKeyFile(String url, String requestStr) throws WxErrorException { | ||||
|   	try { | ||||
|   		 | ||||
|   		SSLContext sslcontext = getConfig().getSSLContext(); | ||||
|   		if(null==sslcontext){ | ||||
|   			throw new Exception("请将配置类(WxMpInMemoryConfigStorage)中的SSLContext初始化"); | ||||
|   		} | ||||
|   		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, | ||||
|   				new DefaultHostnameVerifier()); | ||||
|   		 | ||||
|   		HttpPost httpPost = new HttpPost(url); | ||||
|   		if (this.wxMpService.getHttpProxy() != null) { | ||||
|   			httpPost.setConfig(RequestConfig.custom().setProxy(this.wxMpService.getHttpProxy()).build()); | ||||
|   		} | ||||
|   		 | ||||
|   		try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build()) { | ||||
|   			httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1"))); | ||||
|   			try (CloseableHttpResponse response = httpclient.execute(httpPost)) { | ||||
|   				String result = EntityUtils.toString(response.getEntity(), Consts.UTF_8); | ||||
|   				this.log.debug("\n[URL]:  {}\n[PARAMS]: {}\n[RESPONSE]: {}", url, requestStr, result); | ||||
|   				return result; | ||||
|   			} | ||||
|   		} finally { | ||||
|   			httpPost.releaseConnection(); | ||||
|   		} | ||||
|   	} catch (Exception e) { | ||||
|   		this.log.error("\n[URL]:  {}\n[PARAMS]: {}\n[EXCEPTION]: {}", url, requestStr, e.getMessage()); | ||||
|   		throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg(e.getMessage()).build(), e); | ||||
|   	} | ||||
|   } | ||||
|    | ||||
|   @Override | ||||
|   public String createSign(Object xmlBean) { | ||||
|     return createSign(BeanUtils.xmlBean2Map(xmlBean), getConfig().getPartnerKey()); | ||||
|  | ||||
| @ -20,8 +20,8 @@ import org.apache.http.HttpHost; | ||||
| import org.apache.http.client.config.RequestConfig; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpGet; | ||||
| import org.apache.http.conn.ssl.DefaultHostnameVerifier; | ||||
| import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | ||||
| //import org.apache.http.conn.ssl.DefaultHostnameVerifier; | ||||
| //import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | ||||
| import org.apache.http.impl.client.BasicResponseHandler; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.slf4j.Logger; | ||||
| @ -33,7 +33,7 @@ import java.util.concurrent.locks.Lock; | ||||
| public class WxMpServiceImpl implements WxMpService { | ||||
|  | ||||
|   private static final JsonParser JSON_PARSER = new JsonParser(); | ||||
|  | ||||
|    | ||||
|   protected final Logger log = LoggerFactory.getLogger(this.getClass()); | ||||
|  | ||||
|   private WxMpConfigStorage configStorage; | ||||
| @ -459,12 +459,12 @@ public class WxMpServiceImpl implements WxMpService { | ||||
|         .httpProxyUsername(this.configStorage.getHttpProxyUsername()) | ||||
|         .httpProxyPassword(this.configStorage.getHttpProxyPassword()); | ||||
|  | ||||
|     if (this.configStorage.getSSLContext() != null) { | ||||
|       SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( | ||||
|           this.configStorage.getSSLContext(), new String[] { "TLSv1" }, null, | ||||
|           new DefaultHostnameVerifier()); | ||||
|       apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); | ||||
|     } | ||||
| 		// if (this.configStorage.getSSLContext() != null) { | ||||
| 		// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( | ||||
| 		// this.configStorage.getSSLContext(), new String[] { "TLSv1" }, null, | ||||
| 		// new DefaultHostnameVerifier()); | ||||
| 		// apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf); | ||||
| 		// } | ||||
|  | ||||
|     if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { | ||||
|       this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 408033187@qq.com
					408033187@qq.com