certificate file bug fixed

This commit is contained in:
jinyu 2017-07-11 17:13:07 +08:00
parent c439e38915
commit bee75e55cf
3 changed files with 330 additions and 340 deletions

View File

@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.api;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@ -16,6 +17,7 @@ import com.foxinmy.weixin4j.sign.WeixinSignature;
import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.util.RandomUtil; import com.foxinmy.weixin4j.util.RandomUtil;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/** /**
* 商户支付 * 商户支付
@ -28,101 +30,100 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class MchApi extends BaseApi { public class MchApi extends BaseApi {
private final static ResourceBundle WEIXIN_BUNDLE; private final static ResourceBundle WEIXIN_BUNDLE;
static { static {
WEIXIN_BUNDLE = ResourceBundle WEIXIN_BUNDLE = ResourceBundle.getBundle("com/foxinmy/weixin4j/payment/weixin");
.getBundle("com/foxinmy/weixin4j/payment/weixin"); }
}
protected final WeixinPayAccount weixinAccount; protected final WeixinPayAccount weixinAccount;
protected final WeixinSignature weixinSignature; protected final WeixinSignature weixinSignature;
private volatile WeixinRequestExecutor weixinSSLExecutor; private volatile WeixinRequestExecutor weixinSSLExecutor;
public MchApi(WeixinPayAccount weixinAccount) { public MchApi(WeixinPayAccount weixinAccount) {
this.weixinAccount = weixinAccount; this.weixinAccount = weixinAccount;
this.weixinSignature = new WeixinPaymentSignature( this.weixinSignature = new WeixinPaymentSignature(weixinAccount.getPaySignKey());
weixinAccount.getPaySignKey()); }
}
@Override @Override
protected ResourceBundle weixinBundle() { protected ResourceBundle weixinBundle() {
return WEIXIN_BUNDLE; return WEIXIN_BUNDLE;
} }
/** /**
* 支付接口请求基本数据 * 支付接口请求基本数据
* *
* @param idQuery * @param idQuery
* ID信息 可为空 * ID信息 可为空
* @return 基础map * @return 基础map
*/ */
protected Map<String, String> createBaseRequestMap(IdQuery idQuery) { protected Map<String, String> createBaseRequestMap(IdQuery idQuery) {
Map<String, String> map = new HashMap<String, String>(); Map<String, String> map = new HashMap<String, String>();
map.put("appid", weixinAccount.getId()); map.put("appid", weixinAccount.getId());
map.put("mch_id", weixinAccount.getMchId()); map.put("mch_id", weixinAccount.getMchId());
map.put("nonce_str", RandomUtil.generateString(16)); map.put("nonce_str", RandomUtil.generateString(16));
if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) { if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
map.put("device_info", weixinAccount.getDeviceInfo()); map.put("device_info", weixinAccount.getDeviceInfo());
} }
if (StringUtil.isNotBlank(weixinAccount.getSubId())) { if (StringUtil.isNotBlank(weixinAccount.getSubId())) {
map.put("sub_appid", weixinAccount.getSubId()); map.put("sub_appid", weixinAccount.getSubId());
} }
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) { if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
map.put("sub_mch_id", weixinAccount.getSubMchId()); map.put("sub_mch_id", weixinAccount.getSubMchId());
} }
if (idQuery != null) { if (idQuery != null) {
map.put(idQuery.getType().getName(), idQuery.getId()); map.put(idQuery.getType().getName(), idQuery.getId());
} }
return map; return map;
} }
/** /**
* 微信签名类 * 微信签名类
* *
* @return * @return
*/ */
public WeixinSignature getWeixinSignature() { public WeixinSignature getWeixinSignature() {
return this.weixinSignature; return this.weixinSignature;
} }
/** /**
* 微信SSL * 微信SSL
* *
* @return * @return
*/ */
protected WeixinRequestExecutor getWeixinSSLExecutor() protected WeixinRequestExecutor getWeixinSSLExecutor() throws WeixinException {
throws WeixinException { if (weixinSSLExecutor == null) {
if (weixinSSLExecutor == null) { try {
try { InputStream is = null;
File certificate = new File(weixinAccount.getCertificateFile()); File certificate = new File(
if (!certificate.exists() || !certificate.isFile()) { Weixin4jConfigUtil.replaceClassPathValue(weixinAccount.getCertificateFile()));
throw new WeixinException("Invalid certificate file : " if (!certificate.exists() || !certificate.isFile()) {
+ certificate.toString()); is = Weixin4jConfigUtil.CLASSLOADER.getResourceAsStream(weixinAccount.getCertificateFile());
} } else {
this.weixinSSLExecutor = weixinExecutor is = new FileInputStream(certificate);
.createSSLRequestExecutor( }
weixinAccount.getCertificateKey(), if (is == null) {
new FileInputStream(certificate)); throw new WeixinException("Invalid certificate file : " + certificate.toString());
} catch (IOException e) { }
throw new WeixinException( this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getCertificateKey(), is);
"IO Error on createSSLRequestExecutor", e); } catch (IOException e) {
} throw new WeixinException("IO Error on createSSLRequestExecutor", e);
} }
return this.weixinSSLExecutor; }
} return this.weixinSSLExecutor;
}
/** /**
* 设置商户信息 * 设置商户信息
* *
* @param merchant * @param merchant
*/ */
protected <T extends MerchantResult> void declareMerchant(T merchant) { protected <T extends MerchantResult> void declareMerchant(T merchant) {
merchant.setAppId(weixinAccount.getId()); merchant.setAppId(weixinAccount.getId());
merchant.setMchId(weixinAccount.getMchId()); merchant.setMchId(weixinAccount.getMchId());
merchant.setDeviceInfo(weixinAccount.getDeviceInfo()); merchant.setDeviceInfo(weixinAccount.getDeviceInfo());
merchant.setSubAppId(weixinAccount.getSubId()); merchant.setSubAppId(weixinAccount.getSubId());
merchant.setSubMchId(weixinAccount.getSubMchId()); merchant.setSubMchId(weixinAccount.getSubMchId());
merchant.setNonceStr(RandomUtil.generateString(16)); merchant.setNonceStr(RandomUtil.generateString(16));
} }
} }

View File

@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.model;
import com.alibaba.fastjson.annotation.JSONCreator; import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/** /**
* 微信支付账户 * 微信支付账户
@ -16,183 +15,175 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
*/ */
public class WeixinPayAccount extends WeixinAccount { public class WeixinPayAccount extends WeixinAccount {
private static final long serialVersionUID = -2791256176906048632L; private static final long serialVersionUID = -2791256176906048632L;
/** /**
* 公众号支付请求中用于加密的密钥 * 公众号支付请求中用于加密的密钥
*/ */
private final String paySignKey; private final String paySignKey;
/** /**
* 微信支付分配的商户号 * 微信支付分配的商户号
*/ */
private final String mchId; private final String mchId;
/** /**
* 加载支付证书文件的密码(默认为商户号) * 加载支付证书文件的密码(默认为商户号)
*/ */
private String certificateKey; private String certificateKey;
/** /**
* 商户证书文件(默认加载classpath:ca.p12) * 商户证书文件(默认加载classpath:ca.p12)
*/ */
private String certificateFile; private String certificateFile;
/** /**
* 微信支付分配的设备号 * 微信支付分配的设备号
*/ */
private String deviceInfo; private String deviceInfo;
/** /**
* 财付通商户身份的标识 * 财付通商户身份的标识
*/ */
private String partnerId; private String partnerId;
/** /**
* 微信分配的子商户公众账号ID * 微信分配的子商户公众账号ID
*/ */
private String subId; private String subId;
/** /**
* 微信支付分配的子商户号 * 微信支付分配的子商户号
*/ */
private String subMchId; private String subMchId;
/** /**
* 支付商户信息 * 支付商户信息
* *
* @param id * @param id
* 公众号唯一的身份ID(必填) * 公众号唯一的身份ID(必填)
* @param paySignKey * @param paySignKey
* 支付密钥字符串(必填) * 支付密钥字符串(必填)
* @param mchId * @param mchId
* 微信支付分配的商户号(必填) * 微信支付分配的商户号(必填)
*/ */
public WeixinPayAccount(String id, String paySignKey, String mchId) { public WeixinPayAccount(String id, String paySignKey, String mchId) {
this(id, paySignKey, mchId, mchId, "classpath:ca.p12"); this(id, paySignKey, mchId, mchId, "classpath:ca.p12");
} }
/** /**
* 支付商户信息 * 支付商户信息
* *
* @param id * @param id
* 公众号唯一的身份ID(必填) * 公众号唯一的身份ID(必填)
* @param paySignKey * @param paySignKey
* 支付密钥字符串(必填) * 支付密钥字符串(必填)
* @param mchId * @param mchId
* 微信支付分配的商户号(必填) * 微信支付分配的商户号(必填)
* @param certificateKey * @param certificateKey
* 加载支付证书文件的密码(默认为商户号) * 加载支付证书文件的密码(默认为商户号)
* @param certificateFile * @param certificateFile
* 商户证书文件(默认加载classpath:ca.p12) * 商户证书文件(默认加载classpath:ca.p12)
*/ */
public WeixinPayAccount(String id, String paySignKey, String mchId, public WeixinPayAccount(String id, String paySignKey, String mchId, String certificateKey, String certificateFile) {
String certificateKey, String certificateFile) { this(id, null, paySignKey, mchId, certificateKey, certificateFile, null, null, null, null);
this(id, null, paySignKey, mchId, certificateKey, certificateFile, }
null, null, null, null);
}
/** /**
* 支付商户信息 * 支付商户信息
* *
* @param id * @param id
* 公众号唯一的身份ID(必填) * 公众号唯一的身份ID(必填)
* @param secret * @param secret
* 公众号调用接口的凭证(最好填写) * 公众号调用接口的凭证(最好填写)
* @param paySignKey * @param paySignKey
* 支付密钥字符串(必填) * 支付密钥字符串(必填)
* @param mchId * @param mchId
* 微信支付分配的商户号(必填) * 微信支付分配的商户号(必填)
* @param certificateKey * @param certificateKey
* 加载支付证书文件的密码(默认为商户号) * 加载支付证书文件的密码(默认为商户号)
* @param certificateFile * @param certificateFile
* 商户证书文件(默认加载classpath:ca.p12) * 商户证书文件(默认加载classpath:ca.p12)
* @param deviceInfo * @param deviceInfo
* 微信支付分配的设备号(非必填) * 微信支付分配的设备号(非必填)
* @param partnerId * @param partnerId
* 财付通的商户号(非必填) * 财付通的商户号(非必填)
* @param subId * @param subId
* 微信分配的子商户公众账号ID(非必填) * 微信分配的子商户公众账号ID(非必填)
* @param subMchId * @param subMchId
* 微信支付分配的子商户号(非必填) * 微信支付分配的子商户号(非必填)
*/ */
@JSONCreator @JSONCreator
public WeixinPayAccount(@JSONField(name = "id") String id, public WeixinPayAccount(@JSONField(name = "id") String id, @JSONField(name = "secret") String secret,
@JSONField(name = "secret") String secret, @JSONField(name = "paySignKey") String paySignKey, @JSONField(name = "mchId") String mchId,
@JSONField(name = "paySignKey") String paySignKey, @JSONField(name = "certificateKey") String certificateKey,
@JSONField(name = "mchId") String mchId, @JSONField(name = "certificateFile") String certificateFile,
@JSONField(name = "certificateKey") String certificateKey, @JSONField(name = "deviceInfo") String deviceInfo, @JSONField(name = "partnerId") String partnerId,
@JSONField(name = "certificateFile") String certificateFile, @JSONField(name = "subId") String subId, @JSONField(name = "subMchId") String subMchId) {
@JSONField(name = "deviceInfo") String deviceInfo, super(id, secret);
@JSONField(name = "partnerId") String partnerId, this.paySignKey = paySignKey;
@JSONField(name = "subId") String subId, this.mchId = mchId;
@JSONField(name = "subMchId") String subMchId) { this.certificateKey = certificateKey;
super(id, secret); this.certificateFile = certificateFile;
this.paySignKey = paySignKey; this.deviceInfo = deviceInfo;
this.mchId = mchId; this.partnerId = partnerId;
this.certificateKey = certificateKey; this.subId = subId;
this.certificateFile = certificateFile; this.subMchId = subMchId;
this.deviceInfo = deviceInfo; }
this.partnerId = partnerId;
this.subId = subId;
this.subMchId = subMchId;
}
public String getPaySignKey() { public String getPaySignKey() {
return paySignKey; return paySignKey;
} }
public String getMchId() { public String getMchId() {
return mchId; return mchId;
} }
public String getDeviceInfo() { public String getDeviceInfo() {
return deviceInfo; return deviceInfo;
} }
public String getCertificateKey() { public String getCertificateKey() {
return StringUtil.isBlank(certificateKey) ? mchId : certificateKey; return StringUtil.isBlank(certificateKey) ? mchId : certificateKey;
} }
public String getPartnerId() { public String getPartnerId() {
return partnerId; return partnerId;
} }
public String getSubId() { public String getSubId() {
return subId; return subId;
} }
public String getSubMchId() { public String getSubMchId() {
return subMchId; return subMchId;
} }
public void setCertificateKey(String certificateKey) { public void setCertificateKey(String certificateKey) {
this.certificateKey = certificateKey; this.certificateKey = certificateKey;
} }
public String getCertificateFile() { public String getCertificateFile() {
return Weixin4jConfigUtil.replaceClassPathValue(certificateFile); return certificateFile;
} }
public void setCertificateFile(String certificateFile) { public void setCertificateFile(String certificateFile) {
this.certificateFile = certificateFile; this.certificateFile = certificateFile;
} }
public void setDeviceInfo(String deviceInfo) { public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo; this.deviceInfo = deviceInfo;
} }
public void setPartnerId(String partnerId) { public void setPartnerId(String partnerId) {
this.partnerId = partnerId; this.partnerId = partnerId;
} }
public void setSubId(String subId) { public void setSubId(String subId) {
this.subId = subId; this.subId = subId;
} }
public void setSubMchId(String subMchId) { public void setSubMchId(String subMchId) {
this.subMchId = subMchId; this.subMchId = subMchId;
} }
@Override @Override
public String toString() { public String toString() {
return "WeixinPayAccount [" + super.toString() + ", paySignKey=" return "WeixinPayAccount [" + super.toString() + ", paySignKey=" + paySignKey + ", mchId=" + mchId
+ paySignKey + ", mchId=" + mchId + ", certificateKey=" + ", certificateKey=" + certificateKey + ",certificateFile =" + certificateFile + ", deviceInfo="
+ certificateKey + ",certificateFile =" + certificateFile + deviceInfo + ", partnerId=" + partnerId + ", subId=" + subId + ", subMchId=" + subMchId + "]";
+ ", deviceInfo=" + deviceInfo + ", partnerId=" + partnerId }
+ ", subId=" + subId + ", subMchId=" + subMchId + "]";
}
} }

View File

@ -16,102 +16,100 @@ import com.foxinmy.weixin4j.model.WeixinAccount;
* @see * @see
*/ */
public class Weixin4jConfigUtil { public class Weixin4jConfigUtil {
private final static String CLASSPATH_PREFIX = "classpath:"; private final static String CLASSPATH_PREFIX = "classpath:";
private final static String CLASSPATH_VALUE; private final static String CLASSPATH_VALUE;
private static ResourceBundle weixinBundle; public final static ClassLoader CLASSLOADER;
static { private static ResourceBundle weixinBundle;
CLASSPATH_VALUE = Thread.currentThread().getContextClassLoader() static {
.getResource("").getPath(); CLASSLOADER = Thread.currentThread().getContextClassLoader();
try { CLASSPATH_VALUE = CLASSLOADER.getResource("").getPath();
weixinBundle = ResourceBundle.getBundle(Consts.WEIXIN4J); try {
} catch (MissingResourceException e) { weixinBundle = ResourceBundle.getBundle(Consts.WEIXIN4J);
; } catch (MissingResourceException e) {
} ;
} }
}
private final static String WEIXIN4J_PREFIX = "weixin4j"; private final static String WEIXIN4J_PREFIX = "weixin4j";
private static String wrapKeyName(String key) { private static String wrapKeyName(String key) {
if (!key.startsWith(WEIXIN4J_PREFIX)) { if (!key.startsWith(WEIXIN4J_PREFIX)) {
return String.format("%s.%s", WEIXIN4J_PREFIX, key); return String.format("%s.%s", WEIXIN4J_PREFIX, key);
} }
return key; return key;
} }
/** /**
* 获取weixin4j.properties文件中的key值 * 获取weixin4j.properties文件中的key值
* *
* @param key * @param key
* @return * @return
*/ */
public static String getValue(String key) { public static String getValue(String key) {
String wrapKey = wrapKeyName(key); String wrapKey = wrapKeyName(key);
return System.getProperty(wrapKey, weixinBundle.getString(wrapKey)); return System.getProperty(wrapKey, weixinBundle.getString(wrapKey));
} }
/** /**
* key不存在时则返回传入的默认值 * key不存在时则返回传入的默认值
* *
* @param key * @param key
* @param defaultValue * @param defaultValue
* @return * @return
*/ */
public static String getValue(String key, String defaultValue) { public static String getValue(String key, String defaultValue) {
String value = defaultValue; String value = defaultValue;
try { try {
value = getValue(key); value = getValue(key);
if (StringUtil.isBlank(value)) { if (StringUtil.isBlank(value)) {
value = defaultValue; value = defaultValue;
} }
} catch (MissingResourceException e) { } catch (MissingResourceException e) {
; ;
} catch (NullPointerException e) { } catch (NullPointerException e) {
; ;
} }
return value; return value;
} }
/** /**
* 判断属性是否存在[classpath:]如果存在则拼接项目路径后返回 一般用于文件的绝对路径获取 * 判断属性是否存在[classpath:]如果存在则拼接项目路径后返回 一般用于文件的绝对路径获取
* *
* @param key * @param key
* @return * @return
*/ */
public static String getClassPathValue(String key) { public static String getClassPathValue(String key) {
return replaceClassPathValue(getValue(key)); return replaceClassPathValue(getValue(key));
} }
/** /**
* *
* @param key * @param key
* @param defaultValue * @param defaultValue
* @return * @return
*/ */
public static String getClassPathValue(String key, String defaultValue) { public static String getClassPathValue(String key, String defaultValue) {
return replaceClassPathValue(getValue(key, defaultValue)); return replaceClassPathValue(getValue(key, defaultValue));
} }
public static String replaceClassPathValue(String value) { public static String replaceClassPathValue(String value) {
return value.replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE); return value.replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE);
} }
/** /**
* 获取微信账号信息 * 获取微信账号信息
* *
* @return 微信账号信息 * @return 微信账号信息
*/ */
public static WeixinAccount getWeixinAccount() { public static WeixinAccount getWeixinAccount() {
WeixinAccount account = null; WeixinAccount account = null;
try { try {
account = JSON account = JSON.parseObject(getValue("account"), WeixinAccount.class);
.parseObject(getValue("account"), WeixinAccount.class); } catch (NullPointerException e) {
} catch (NullPointerException e) { System.err.println("'weixin4j.account' key not found in weixin4j.properties.");
System.err } catch (MissingResourceException e) {
.println("'weixin4j.account' key not found in weixin4j.properties."); System.err.println("'weixin4j.account' key not found in weixin4j.properties.");
} catch (MissingResourceException e) { }
System.err return account;
.println("'weixin4j.account' key not found in weixin4j.properties."); }
}
return account;
}
} }