本文共 32247 字,大约阅读时间需要 107 分钟。
最近断断续续花了接近一个月的时间把微信支付的调研工作加写代码完成,然后一次myeclipse出了一些问题,我想把它卸载了再重装一下,然后就傻了眼了。由于之前很傻比的把工作空间放在了myeclipse的安装目录下面,导致代码全部丢失了。由于工作上的代码都在SVN上都有,但是微信支付的代码还没有上传上去,感觉一下子人生都灰暗了(有点夸张)。
痛定思痛,只有凭印象重写一遍,虽然微信支付的代码不算很多,但是要整合自己的项目上去,工作量还是有一些的。经过两天的奋战,总算写完了,为了避免之前的悲剧,同时为了以后更方便的回忆,所以决定在备份了一份后,再把他给贴出来。
代码主要分为三个大的部分:统一下单,支付结果通知和查询订单。里面有整合自己的业务。
统一下单(WeChatPayServerServlet)
package com.zhuyun.wechatpay.servlet;import java.io.IOException;import java.io.PrintWriter;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.RandomStringUtils;import com.zhuyun.wechatpay.dao.OrderDao;import com.zhuyun.wechatpay.dao.impl.OrderDaoImpl;import com.zhuyun.wechatpay.entity.OrderInfo;import com.zhuyun.wechatpay.util.IPUtil;import com.zhuyun.wechatpay.util.MD5Util;import com.zhuyun.wechatpay.util.WeUtil;import com.zhuyun.wechatpay.util.XmlParseUtil;public class WeChatPayServerServlet extends HttpServlet { public WeChatPayServerServlet() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //把请求的xml数据解析成有序的map格式 SortedMap map = new TreeMap(); map = XmlParseUtil.xmlToMap(request); String signValidate = MD5Util.createSign("UTF-8", map); String appid = map.get("appid"); String mch_id = map.get("mch_id"); String deviceIds = map.get("deviceIds"); String sign = map.get("sign"); int appLifeTime = Integer.parseInt(map.get("appLifeTime")); //计算总额 String[] strings = deviceIds.split("_"); int total_fee = IPUtil.unit_price * strings.length * appLifeTime; System.out.println("缴费总额:" + total_fee); System.out.println("appid:" + appid); System.out.println("mch_id:" + mch_id); System.out.println("deviceIds:" + deviceIds); //验证客户端签名 if (signValidate.equals(sign)) { System.out.println("客户端签名验证通过"); String nonce_str = RandomStringUtils.randomAlphanumeric(32); String body = "设备:" + strings.length + "台, 续费年限:" + appLifeTime + "年"; String out_trade_no = WeUtil.createOutTradeNo(); String spbill_create_ip = request.getRemoteAddr(); String notify_url = "https://zhuyun.f3322.net:443/WeChatPay/weChatPayNotice"; String trade_type = "APP"; //生成签名,发送给微信支付系统 map = new TreeMap(); map.put("appid", appid); map.put("mch_id", mch_id); map.put("nonce_str", nonce_str); map.put("body", body); map.put("out_trade_no", out_trade_no); map.put("total_fee", total_fee + ""); map.put("spbill_create_ip", spbill_create_ip); map.put("notify_url", notify_url); map.put("trade_type", trade_type); sign = MD5Util.createSign("UTF-8", map); //发送统一下单数据,接收返回结果 String unifiedorder = "" + "" + appid + "" + "" + mch_id + "" + "" + nonce_str + "" + "" + body + "" + "" + out_trade_no + "" + "" + total_fee + "" + "" + spbill_create_ip + "" + "" + notify_url + "" + "" + trade_type + "" + "" + sign + "" + ""; String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String res = WeUtil.httpRequest(url, "POST", unifiedorder); System.out.println(res); //对返回结果进行签名验证 map = XmlParseUtil.xmlToMap(res); String return_code = map.get("return_code"); if ("SUCCESS".equals(return_code)) { sign = map.get("sign"); signValidate = MD5Util.createSign("UTF-8", map); if (sign.equals(signValidate)) { System.out.println("微信支付系统端签名验证成功"); appid = map.get("appid"); mch_id = map.get("mch_id"); nonce_str = map.get("nonce_str"); String result_code = map.get("result_code"); if ("SUCCESS".equals(result_code)) { trade_type = map.get("trade_type"); String prepay_id = map.get("prepay_id"); //验证成功后,需要把订单保存到本地服务器,并把resultCode设置为FAIL, //当支付结果成功,并受到通知以后,再设置为SUCCESS OrderInfo orderInfo = new OrderInfo(); orderInfo.setAppLifeTime(appLifeTime); orderInfo.setBody(body); orderInfo.setDeviceIds(deviceIds); orderInfo.setOutTradeNo(out_trade_no); orderInfo.setResultCode("FAIL"); orderInfo.setTimeExpire(""); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); orderInfo.setTimeStart(sdf.format(date)); orderInfo.setTotalFee(total_fee); orderInfo.setTradeType("APP"); orderInfo.setTransactionId(""); OrderDao orderDao = new OrderDaoImpl(); orderDao.saveOrderInfo(orderInfo); //签名 long timestamp = System.currentTimeMillis(); map = new TreeMap(); map.put("return_code", return_code); map.put("appid", appid); map.put("mch_id", mch_id); map.put("nonce_str", nonce_str); map.put("result_code", result_code); map.put("trade_type", trade_type); map.put("prepay_id", prepay_id); map.put("timestamp", timestamp + ""); sign = MD5Util.createSign("UTF-8", map); //把内容返回给APP String toReturn = "" + "" + return_code + "" + "" + appid + "" + "" + mch_id + "" + "" + nonce_str + "" + "" + result_code + "" + "" + trade_type + "" + "" + prepay_id + "" + "" + timestamp + "" + "" + sign + "" + ""; out.print(toReturn); out.flush(); out.close(); }else if("FAIL".equals(result_code)){ System.out.println("交易失败"); out.print(res); out.flush(); out.close(); } } } }else { System.out.println("客户端签名验证失败"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { // Put your code here }} map = new TreeMap(); map = XmlParseUtil.xmlToMap(request); String signValidate = MD5Util.createSign("UTF-8", map); String appid = map.get("appid"); String mch_id = map.get("mch_id"); String deviceIds = map.get("deviceIds"); String sign = map.get("sign"); int appLifeTime = Integer.parseInt(map.get("appLifeTime")); //计算总额 String[] strings = deviceIds.split("_"); int total_fee = IPUtil.unit_price * strings.length * appLifeTime; System.out.println("缴费总额:" + total_fee); System.out.println("appid:" + appid); System.out.println("mch_id:" + mch_id); System.out.println("deviceIds:" + deviceIds); //验证客户端签名 if (signValidate.equals(sign)) { System.out.println("客户端签名验证通过"); String nonce_str = RandomStringUtils.randomAlphanumeric(32); String body = "设备:" + strings.length + "台, 续费年限:" + appLifeTime + "年"; String out_trade_no = WeUtil.createOutTradeNo(); String spbill_create_ip = request.getRemoteAddr(); String notify_url = "https://zhuyun.f3322.net:443/WeChatPay/weChatPayNotice"; String trade_type = "APP"; //生成签名,发送给微信支付系统 map = new TreeMap(); map.put("appid", appid); map.put("mch_id", mch_id); map.put("nonce_str", nonce_str); map.put("body", body); map.put("out_trade_no", out_trade_no); map.put("total_fee", total_fee + ""); map.put("spbill_create_ip", spbill_create_ip); map.put("notify_url", notify_url); map.put("trade_type", trade_type); sign = MD5Util.createSign("UTF-8", map); //发送统一下单数据,接收返回结果 String unifiedorder = "" + "" + appid + "" + "" + mch_id + "" + "" + nonce_str + "" + "
" + body + "
" + "" + out_trade_no + "" + "" + total_fee + "" + "" + spbill_create_ip + "" + "" + notify_url + "" + "" + trade_type + "" + "" + sign + "" + ""; String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String res = WeUtil.httpRequest(url, "POST", unifiedorder); System.out.println(res); //对返回结果进行签名验证 map = XmlParseUtil.xmlToMap(res); String return_code = map.get("return_code"); if ("SUCCESS".equals(return_code)) { sign = map.get("sign"); signValidate = MD5Util.createSign("UTF-8", map); if (sign.equals(signValidate)) { System.out.println("微信支付系统端签名验证成功"); appid = map.get("appid"); mch_id = map.get("mch_id"); nonce_str = map.get("nonce_str"); String result_code = map.get("result_code"); if ("SUCCESS".equals(result_code)) { trade_type = map.get("trade_type"); String prepay_id = map.get("prepay_id"); //验证成功后,需要把订单保存到本地服务器,并把resultCode设置为FAIL, //当支付结果成功,并受到通知以后,再设置为SUCCESS OrderInfo orderInfo = new OrderInfo(); orderInfo.setAppLifeTime(appLifeTime); orderInfo.setBody(body); orderInfo.setDeviceIds(deviceIds); orderInfo.setOutTradeNo(out_trade_no); orderInfo.setResultCode("FAIL"); orderInfo.setTimeExpire(""); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); orderInfo.setTimeStart(sdf.format(date)); orderInfo.setTotalFee(total_fee); orderInfo.setTradeType("APP"); orderInfo.setTransactionId(""); OrderDao orderDao = new OrderDaoImpl(); orderDao.saveOrderInfo(orderInfo); //签名 long timestamp = System.currentTimeMillis(); map = new TreeMap(); map.put("return_code", return_code); map.put("appid", appid); map.put("mch_id", mch_id); map.put("nonce_str", nonce_str); map.put("result_code", result_code); map.put("trade_type", trade_type); map.put("prepay_id", prepay_id); map.put("timestamp", timestamp + ""); sign = MD5Util.createSign("UTF-8", map); //把内容返回给APP String toReturn = "" + "" + return_code + "" + "" + appid + "" + "" + mch_id + "" + "" + nonce_str + "" + "" + result_code + "" + "" + trade_type + "" + "" + prepay_id + "" + "" + timestamp + "" + "" + sign + "" + ""; out.print(toReturn); out.flush(); out.close(); }else if("FAIL".equals(result_code)){ System.out.println("交易失败"); out.print(res); out.flush(); out.close(); } } } }else { System.out.println("客户端签名验证失败"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { // Put your code here } }
支付结果通知(WeChatPayNoticeServlet.java)
package com.zhuyun.wechatpay.servlet;import java.io.IOException;import java.io.PrintWriter;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.SortedMap;import java.util.TreeMap;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.zhuyun.wechatpay.dao.OrderDao;import com.zhuyun.wechatpay.dao.ProductDao;import com.zhuyun.wechatpay.dao.impl.OrderDaoImpl;import com.zhuyun.wechatpay.dao.impl.ProductDaoImpl;import com.zhuyun.wechatpay.entity.OrderInfo;import com.zhuyun.wechatpay.entity.ProductInfo;import com.zhuyun.wechatpay.util.MD5Util;import com.zhuyun.wechatpay.util.XmlParseUtil;public class WeChatPayNoticeServlet extends HttpServlet { public WeChatPayNoticeServlet() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //把请求的xml数据解析成有序的map格式 SortedMap map = new TreeMap(); map = XmlParseUtil.xmlToMap(request); String return_code = map.get("return_code"); if ("SUCCESS".equals(return_code)) { String signValidate = MD5Util.createSign("UTF-8", map); String sign = map.get("sign"); if (sign.equals(signValidate)) { //支付通知的签名验证成功 System.out.println("支付结果通知签名验证成功"); String result_code = map.get("result_code"); if ("SUCCESS".equals(result_code)) { //支付成功 System.out.println("支付成功"); String toReturn = "" + "" + "" + ""; out.print(toReturn); out.flush(); out.close(); //修改数据库里的订单信息 String out_trade_no = map.get("out_trade_no"); String transaction_id = map.get("transaction_id"); String time_end = map.get("time_end"); OrderDao orderDao = new OrderDaoImpl(); ProductDao productDao = new ProductDaoImpl(); OrderInfo orderInfo = orderDao.getOrderInfo(out_trade_no); if (orderInfo != null) { String resultCode = orderInfo.getResultCode(); if ("FAIL".equals(resultCode)) { //1,把订单状态改成SUCCESS //2,把微信订单号和交易完成时间更新进去 //3,修改设备的有效期 orderInfo.setResultCode("SUCCESS"); orderInfo.setTransactionId(transaction_id); orderInfo.setTimeExpire(time_end); orderDao.updateOrderInfo(orderInfo); String deviceIds = orderInfo.getDeviceIds(); int appLifeTime = orderInfo.getAppLifeTime(); String[] devices = deviceIds.split("_"); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); for (String device : devices) { ProductInfo productInfo = productDao.getProductInfoByDeviceId(device); String appExpireTime = productInfo.getAppExpireTime(); //续费时间在产品过期之前,此时把appLifeTime加上续费的时间,appExpireTime也加上续费的时间,regTime不变 try { if (date.before(sdf.parse(appExpireTime))) { Calendar calendar = Calendar.getInstance(); calendar.setTime(sdf.parse(appExpireTime)); calendar.add(Calendar.YEAR, appLifeTime); appLifeTime = appLifeTime + productInfo.getAppLifeTime(); productInfo.setAppExpireTime(sdf.format(calendar.getTime())); productInfo.setAppLifeTime(appLifeTime); productDao.updateProductInfo(productInfo); System.out.println("设备" + device + "缴费成功"); }else { //续费时间在产品过期之后,此时把regTime设置成当前时间,appLifeTime改成续费时间,appExpireTime改成当前时间加上续费的时间 Date regTime = date; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.YEAR, appLifeTime); productInfo.setRegTime(sdf.format(regTime)); productInfo.setAppExpireTime(sdf.format(calendar.getTime())); productInfo.setAppLifeTime(appLifeTime); productDao.updateProductInfo(productInfo); System.out.println("设备" + device + "缴费成功"); } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }else { System.out.println("订单" + out_trade_no + "已处理过,无需再处理"); } }else { System.out.println("订单" + out_trade_no + "不存在"); } }else { System.out.println("支付失败"); String toReturn = "" + "" + "" + ""; out.print(toReturn); out.flush(); out.close(); } }else { System.out.println("支付结果通知签名验证失败"); String toReturn = "" + "" + "" + ""; out.print(toReturn); out.flush(); out.close(); } }else { System.out.println("通信失败"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { // Put your code here }} map = new TreeMap(); map = XmlParseUtil.xmlToMap(request); String return_code = map.get("return_code"); if ("SUCCESS".equals(return_code)) { String signValidate = MD5Util.createSign("UTF-8", map); String sign = map.get("sign"); if (sign.equals(signValidate)) { //支付通知的签名验证成功 System.out.println("支付结果通知签名验证成功"); String result_code = map.get("result_code"); if ("SUCCESS".equals(result_code)) { //支付成功 System.out.println("支付成功"); String toReturn = "" + "" + "" + ""; out.print(toReturn); out.flush(); out.close(); //修改数据库里的订单信息 String out_trade_no = map.get("out_trade_no"); String transaction_id = map.get("transaction_id"); String time_end = map.get("time_end"); OrderDao orderDao = new OrderDaoImpl(); ProductDao productDao = new ProductDaoImpl(); OrderInfo orderInfo = orderDao.getOrderInfo(out_trade_no); if (orderInfo != null) { String resultCode = orderInfo.getResultCode(); if ("FAIL".equals(resultCode)) { //1,把订单状态改成SUCCESS //2,把微信订单号和交易完成时间更新进去 //3,修改设备的有效期 orderInfo.setResultCode("SUCCESS"); orderInfo.setTransactionId(transaction_id); orderInfo.setTimeExpire(time_end); orderDao.updateOrderInfo(orderInfo); String deviceIds = orderInfo.getDeviceIds(); int appLifeTime = orderInfo.getAppLifeTime(); String[] devices = deviceIds.split("_"); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); for (String device : devices) { ProductInfo productInfo = productDao.getProductInfoByDeviceId(device); String appExpireTime = productInfo.getAppExpireTime(); //续费时间在产品过期之前,此时把appLifeTime加上续费的时间,appExpireTime也加上续费的时间,regTime不变 try { if (date.before(sdf.parse(appExpireTime))) { Calendar calendar = Calendar.getInstance(); calendar.setTime(sdf.parse(appExpireTime)); calendar.add(Calendar.YEAR, appLifeTime); appLifeTime = appLifeTime + productInfo.getAppLifeTime(); productInfo.setAppExpireTime(sdf.format(calendar.getTime())); productInfo.setAppLifeTime(appLifeTime); productDao.updateProductInfo(productInfo); System.out.println("设备" + device + "缴费成功"); }else { //续费时间在产品过期之后,此时把regTime设置成当前时间,appLifeTime改成续费时间,appExpireTime改成当前时间加上续费的时间 Date regTime = date; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.YEAR, appLifeTime); productInfo.setRegTime(sdf.format(regTime)); productInfo.setAppExpireTime(sdf.format(calendar.getTime())); productInfo.setAppLifeTime(appLifeTime); productDao.updateProductInfo(productInfo); System.out.println("设备" + device + "缴费成功"); } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }else { System.out.println("订单" + out_trade_no + "已处理过,无需再处理"); } }else { System.out.println("订单" + out_trade_no + "不存在"); } }else { System.out.println("支付失败"); String toReturn = "" + "" + "" + ""; out.print(toReturn); out.flush(); out.close(); } }else { System.out.println("支付结果通知签名验证失败"); String toReturn = "" + "" + "" + ""; out.print(toReturn); out.flush(); out.close(); } }else { System.out.println("通信失败"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { // Put your code here }}
查询订单(WeChatPayQueryServlet.java)
package com.zhuyun.wechatpay.servlet;import java.io.IOException;import java.io.PrintWriter;import java.util.SortedMap;import java.util.TreeMap;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.RandomStringUtils;import com.zhuyun.wechatpay.util.IPUtil;import com.zhuyun.wechatpay.util.MD5Util;import com.zhuyun.wechatpay.util.WeUtil;import com.zhuyun.wechatpay.util.XmlParseUtil;public class WeChatPayQueryServlet extends HttpServlet { public WeChatPayQueryServlet() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); String appid = request.getParameter("appid"); String mch_id = request.getParameter("mch_id"); String transaction_id = request.getParameter("transaction_id"); String nonce_str = RandomStringUtils.randomAlphanumeric(32); SortedMap map = new TreeMap(); map = XmlParseUtil.xmlToMap(request); String signValidate = MD5Util.createSign("UTF-8", map); String sign = request.getParameter("sign"); if (sign.equals(signValidate)) { System.out.println("APP端签名验证成功"); map = new TreeMap(); map.put("appid", appid); map.put("mch_id", mch_id); map.put("transaction_id", transaction_id); map.put("nonce_str", nonce_str); sign = MD5Util.createSign("UTF-8", map); //发送https查询请求 String queryString = "" + "" + appid + "" + "" + mch_id + "" + "" + transaction_id + "" + "" + nonce_str + "" + "" + sign + ""; String url = "https://api.mch.weixin.qq.com/pay/orderquery"; String res = WeUtil.httpRequest(url, "POST", queryString); System.out.println(res); //解析返回的xml数据 map = XmlParseUtil.xmlToMap(res); sign = map.get("sign"); signValidate = MD5Util.createSign("UTF-8", map); if (sign.equals(signValidate)) { out.print(res); out.flush(); out.close(); }else { System.out.println("微信支付端签名验证失败"); } }else { System.out.println("APP端签名验证失败"); } } public void init() throws ServletException { // Put your code here }} map = new TreeMap(); map = XmlParseUtil.xmlToMap(request); String signValidate = MD5Util.createSign("UTF-8", map); String sign = request.getParameter("sign"); if (sign.equals(signValidate)) { System.out.println("APP端签名验证成功"); map = new TreeMap(); map.put("appid", appid); map.put("mch_id", mch_id); map.put("transaction_id", transaction_id); map.put("nonce_str", nonce_str); sign = MD5Util.createSign("UTF-8", map); //发送https查询请求 String queryString = "" + "" + appid + "" + "" + mch_id + "" + "" + transaction_id + "" + "" + nonce_str + "" + "" + sign + ""; String url = "https://api.mch.weixin.qq.com/pay/orderquery"; String res = WeUtil.httpRequest(url, "POST", queryString); System.out.println(res); //解析返回的xml数据 map = XmlParseUtil.xmlToMap(res); sign = map.get("sign"); signValidate = MD5Util.createSign("UTF-8", map); if (sign.equals(signValidate)) { out.print(res); out.flush(); out.close(); }else { System.out.println("微信支付端签名验证失败"); } }else { System.out.println("APP端签名验证失败"); } } public void init() throws ServletException { // Put your code here }}
之所以用有序的map,是因为签名时需要先排序,把xml数据转成有序的map的的代码:
package com.zhuyun.wechatpay.util;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.util.List;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class XmlParseUtil { public static SortedMap xmlToMap(HttpServletRequest request){ SortedMap map = new TreeMap(); SAXReader reader = new SAXReader(); try { InputStream ins = request.getInputStream(); Document doc = reader.read(ins); Element root = doc.getRootElement(); @SuppressWarnings("unchecked") List list = root.elements(); for (Element e : list) { map.put(e.getName(), e.getText()); } ins.close(); } catch (Exception e) { e.printStackTrace(); } return map; } public static SortedMap xmlToMap(String xmlString){ SortedMap map = new TreeMap(); SAXReader reader = new SAXReader(); try { InputStream ins = new ByteArrayInputStream(xmlString.getBytes()); Document doc = reader.read(ins); Element root = doc.getRootElement(); @SuppressWarnings("unchecked") List list = root.elements(); for (Element e : list) { map.put(e.getName(), e.getText()); } ins.close(); } catch (Exception e) { e.printStackTrace(); } return map; }} xmlToMap(HttpServletRequest request){ SortedMap map = new TreeMap(); SAXReader reader = new SAXReader(); try { InputStream ins = request.getInputStream(); Document doc = reader.read(ins); Element root = doc.getRootElement(); @SuppressWarnings("unchecked") List list = root.elements(); for (Element e : list) { map.put(e.getName(), e.getText()); } ins.close(); } catch (Exception e) { e.printStackTrace(); } return map; } public static SortedMap xmlToMap(String xmlString){ SortedMap map = new TreeMap(); SAXReader reader = new SAXReader(); try { InputStream ins = new ByteArrayInputStream(xmlString.getBytes()); Document doc = reader.read(ins); Element root = doc.getRootElement(); @SuppressWarnings("unchecked") List list = root.elements(); for (Element e : list) { map.put(e.getName(), e.getText()); } ins.close(); } catch (Exception e) { e.printStackTrace(); } return map; }}
生成签名createSign的代码:
package com.zhuyun.wechatpay.util;import java.security.MessageDigest;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.SortedMap;public class MD5Util { private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } public static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString .getBytes())); else resultString = byteArrayToHexString(md.digest(resultString .getBytes(charsetname))); } catch (Exception exception) { } return resultString; } private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; public static String createSign(String characterEncoding,SortedMap parameters){ StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序) Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = entry.getValue(); if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + IPUtil.key); String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; } } parameters){ StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序) Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = entry.getValue(); if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + IPUtil.key); String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; } }
使用加密协议https传送POST数据的接口:需要先在本地服务器上安装证书
package com.zhuyun.wechatpay.util;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.ConnectException;import java.net.URL;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Random;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;public class WeUtil { public static boolean isEmpty(Object object){ if (object == null) { return true; } if ("".equals(object)) { return true; } return false; } public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {// JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { X509TrustManager x509m = new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }; // 创建SSLContext对象,并使用我们指定的信任管理器初始化 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, new TrustManager[] { x509m }, new java.security.SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 当有数据需要提交时 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect();// jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { ce.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return buffer.toString(); } //32位,根据当前系统时间加随机序列来生成订单号 public static String createOutTradeNo() { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String now = sdf.format(date); Random random = new Random(); StringBuffer sb = new StringBuffer(); for(int i=0;i<18;i++){ sb.append(random.nextInt(10)); } return now + sb.toString(); } //生成随机字符串 public static String createNonceStr(int length) { String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); }}
转载地址:http://yxex.baihongyu.com/