项目场景:
提示:之前有写过一篇如何发起携带证书的https请求的工具类
其实我是为了对接企业发款到微信零钱的接口需要携带证书取请求微信官方,既然已经写了工具类,那我就一并上传了我得小demo吧
问题描述:
提示:相信你找到这篇文章的时候,你已经对微信的官方文档有一定的了解了
话不多说直接上代码:MD5.java
package com.yang.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* md5加密算法
* @author Administrator
*
*/
public class MD5 {
// 全局数组
private final static String[] strDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
public MD5() {
}
// 返回形式为数字跟字符串
private static String byteToArrayString(byte bByte) {
int iRet = bByte;
// System.out.println("iRet="+iRet);
if (iRet < 0) {
iRet += 256;
}
int iD1 = iRet / 16;
int iD2 = iRet % 16;
return strDigits[iD1] + strDigits[iD2];
}
// 返回形式只为数字
@SuppressWarnings("unused")
private static String byteToNum(byte bByte) {
int iRet = bByte;
System.out.println("iRet1=" + iRet);
if (iRet < 0) {
iRet += 256;
}
return String.valueOf(iRet);
}
// 转换字节数组为16进制字串
private static String byteToString(byte[] bByte) {
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < bByte.length; i++) {
sBuffer.append(byteToArrayString(bByte[i]));
}
return sBuffer.toString();
}
//获取签名
public static String GetMD5Code(String string,String key) {
string=string+"&key="+key;
// System.out.println("签名字符串:"+string);
String resultString = null;
try {
resultString = new String(string);
MessageDigest md = MessageDigest.getInstance("MD5");
// md.digest() 该函数返回值为存放哈希值结果的byte数组
resultString = byteToString(md.digest(string.getBytes()));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return resultString;
}
/**
* MD5加密算法
*
* 说明:32位加密算法
*
* @param 待加密的数据
* @return 加密结果,全小写的字符串(utf-8)
*/
public static String md5(String s) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
byte[] btInput = s.getBytes("utf-8");
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@SuppressWarnings("static-access")
public static void main(String[] args) {
MD5 getMD5 = new MD5();
System.out.println(getMD5.GetMD5Code("merchantReserved=abc&orderNo=20170485345734","F7MeAxjIcmpd4kua6fIhTPDxC34Ju4Yr"));
}
}
问题描述:
提示:上面的加密工具类有了 现在转换成xml
话不多说直接上代码:Xml.java
package com.yang.util;
import java.util.*;
import net.sf.json.JSONObject;
public class Xml {
/**
* 把数组所有元素排序,并按照�?�参�?=参数值�?�的模式用�??&”字符拼接成字符�?
* @param Map<String, Object> params �?要排序并参与字符拼接的参数组
* @return 拼接后字符串
*/
public static String createLinkString(Map<String, Object> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
Object value = params.get(key);
if (i == keys.size() - 1) {//拼接时,不包括最后一�?&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
/**
* 除去数组中的空�?�和签名参数
* @param Map<String, Object> sArray 签名参数�?
* @return 去掉空�?�与签名参数后的新签名参数组 Map<String, Object>
*/
public static Map<String, Object> paraFilter(Map<String, Object> sArray) {
//创建空的result集合同于接收�?
Map<String, Object> result = new HashMap<String, Object>();
//判断sArray参数不能为空,为空则直接返回空的sArray
if (sArray == null || sArray.size() <= 0) {
return sArray;
}
//遍历Map集合
for (String key : sArray.keySet()) {
//value负责接收sArray的key(每次一个)
Object value = sArray.get(key);
//判断value是空值或key="sign"�?
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")) {
//结束本次循环,进行下�?次循�?
continue;
}
//加入result集合
result.put(key, value);
}
//返回result结果
return result;
}
/**
* Map转换成Xml
* @param map
*/
public static String map2Xmlstring(Map<String,Object> map){
StringBuffer sb = new StringBuffer("");
sb.append("<xml>");
Set<String> set = map.keySet();
for(Iterator<String> it=set.iterator(); it.hasNext();){
String key = it.next();
Object value = map.get(key);
sb.append("<").append(key).append(">");
sb.append(value);
sb.append("</").append(key).append(">");
}
sb.append("</xml>");
return sb.toString();
}
public static JSONObject xml2json(String post) {
// TODO Auto-generated method stub
return null;
}
}
问题描述:
提示:上面两个工具类说明前期准备结束,现在要带着证书发起请求的工具类
话不多说直接上代码:PayUtil.java
package com.yang.util;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public class PayUtil {
/**
* 带证书httpPost请求
* @param url 接口地址
* @param param 参数
* @return
* @throws Exception
*/
public static String sendRedEnvelope(String url, String param) throws Exception {
//PKCS12的密码
String PKCS12 = "1340026301";
//证书地址 写绝对路径靠谱些
String fileRoute = "E:\\javacore1\\WXYE\\src\\apiclient_cert.p12";
//指定读取证书格式为PKCS12
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//读取本机存放的PKCS12证书文件
FileInputStream instream = new FileInputStream(new File(fileRoute));
try {
//指定PKCS12的密码
keyStore.load(instream, PKCS12.toCharArray());
} finally {
instream.close();
}
//指定TLS版本
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, PKCS12.toCharArray())
.build();
//设置httpclient的SSLSocketFactory
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
//这里无需改动
new String[]{"TLSv1"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
StringBuffer stringBuffer = new StringBuffer();
try {
HttpPost httpPost = new HttpPost(url);
InputStream is = new ByteArrayInputStream(param.getBytes("UTF-8"));
//InputStreamEntity严格是对内容和长度相匹配的。用法和BasicHttpEntity类似
InputStreamEntity inputStreamEntity = new InputStreamEntity(is, is.available());
httpPost.setEntity(inputStreamEntity);
CloseableHttpResponse response = httpclient.execute(httpPost);
try {
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(
entity.getContent(), "UTF-8"));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
stringBuffer.append(inputLine);
System.out.println(stringBuffer);
}
} finally {
response.close();
}
} finally {
httpclient.close();
}
return stringBuffer.toString();
}
}
问题描述:
提示:万事俱备三个工具类已完成,现在可以将参数进行请求了
话不多说直接上代码:teest .java
package com.yang.util;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class teest {
public static void main(String[] args) throws Exception {
teest t=new teest();
t.qr_code();
}
//商户账号appid
private String mch_appid="wx85e1111111111";
//mchid商户号
private String mchid="1340111111";
//nonce_str 随机字符串
private String nonce_str=UUID.randomUUID().toString().replace("-", "").toLowerCase();
//key 自己再微信支付后台手动设置的那个
private String key="adfasdflkasjdjfliaj4356kjhlker45";
//签名
private String sign=null;
//商户订单号
private String partner_trade_no = UUID.randomUUID().toString().replace("-", "").toLowerCase();
//用户openid 这个只能是再对应公众号下获取到的用户openid
private String openid="oZ1z9w3xP9SBbO3V4lmKVktsY82s";
//校验用户姓名选项 NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
private String check_name="FORCE_CHECK";
//re_user_name收款用户姓名
private String re_user_name="法外狂徒张三";
//金额 以分为单位
private String amount="100";
//企业付款备注
private String desc="测试打款";
//IP 随意填
private String spbill_create_ip ="101.200.38.333";
public void qr_code() throws Exception {
//Map集合
Map<String,Object> map = new HashMap<String, Object>();
map.put("mch_appid", mch_appid);
map.put("mchid", mchid);
map.put("nonce_str",nonce_str);
map.put("sign",sign);
map.put("partner_trade_no",partner_trade_no);
map.put("openid",openid);
map.put("check_name",check_name);
map.put("re_user_name",re_user_name);
map.put("amount",amount);
map.put("desc",desc);
map.put("spbill_create_ip",spbill_create_ip);
//接收去掉空值与签名参数后的新签名参数组
Map<String, Object> paraFilter = Xml.paraFilter(map);
//接收拼接后的字符串(例如:body=test123&mch_id=100002301645&nonce_str=dbb9...)
String createLinkString =Xml.createLinkString(paraFilter);
System.out.println(createLinkString);
//接收MD5签名
sign = MD5.GetMD5Code(createLinkString, key);
//把签名加入到map集合 并将签名转为大写英文字母
map.put("sign", sign.toUpperCase());
//接收转换的xml字符串
String xmlstring = Xml.map2Xmlstring(map);
System.out.println("请求:"+xmlstring);
//所代表远程资源的响应结果
String sendPost = PayUtil.sendRedEnvelope("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers",xmlstring);
System.out.println("返回:"+sendPost);
}
}
解决方案:
提示:看到这里说明你是有
还是比较迫切的要接这个功能的,这些代码合起来绝对实现代付到微信余额,放心使用