本人新手,找了好长时间都没有找到h5的java开发源码,自己看官方文档研究了两天满满的都是心酸,主要是为自己以后翻看留个记录,以免忘记
申请那一套我就不讲了,首先必须保证打包app时的签名必须和你申请时填写的一致,要不然跑不通的.直接上源码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import util.MD5Util; import util.UtilDate; public class PayTest { HttpServletResponse response = ServletActionContext.getResponse(); private static String Key = "PpKGJMuxmWf9hvK4X3BOJ6gKkfDtGv5D"; private static String appid = "**********";// app的id private static String mch_id = "**********";// 商户号 private static String body = "就是调起微信支付是显示什么";// 备注 private String out_trade_no = UtilDate.getOrderNum();// 商户订单号 private static String spbill_create_ip = getIpAddr();// 终端ip private static String notify_url = "我填的是一个空白页面的地址";// 通知地址 private static String trade_type = "APP";// 支付类型 private static String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; private static String characterEncoding = "UTF-8";// 编码格式 private static String nonce_str = getUUID();// 随机支付串 private String Money;//传过来的钱数 public String getMoney() { return Money; } public void setMoney(String money) { Money = money; } public void WeiXinCZ() { Map map = getSign(); String sjs = getUUID(); String sj = System.currentTimeMillis()+""; sj = sj.substring(0,sj.length()-3); String sjc = sj; SortedMap parameters = new TreeMap(); parameters.put("appid", map.get("appid")); parameters.put("partnerid", map.get("mch_id")); parameters.put("prepayid", map.get("prepay_id")); parameters.put("package", "Sign=WXPay"); parameters.put("noncestr", map.get("nonce_str")); parameters.put("timestamp", sjc); String sign = createSign(characterEncoding, parameters); String str = "{\"appid\":\"" + map.get("appid") + "\",\"partnerid\":\"" + map.get("mch_id") + "\",\"prepayid\":\"" + map.get("prepay_id") + "\",\"package\":\"Sign=WXPay\",\"noncestr\":\"" + map.get("nonce_str") + "\",\"timestamp\":\"" + sjc + "\",\"sign\":\"" + sign + "\"}"; try { this.response.setContentType("text/html;charset=utf-8"); this.response.setHeader("Access-Control-Max-Age", "3600"); this.response.setHeader("Access-Control-Allow-Origin", "*"); this.response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); this.response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); System.out.println(str); PrintWriter out = this.response.getWriter(); out.print(str); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } // 生成预订单 public Map getSign() { try {// 微信api提供的参数 @SuppressWarnings("unused") String total_fee = ((int)(Double.parseDouble(Money) * 100)) + "";// 支付金额 SortedMap parameters = new TreeMap(); parameters.put("appid", appid); parameters.put("mch_id", mch_id); parameters.put("body", body); parameters.put("nonce_str", nonce_str); parameters.put("out_trade_no", out_trade_no); parameters.put("trade_type", trade_type); parameters.put("total_fee", total_fee); parameters.put("spbill_create_ip", spbill_create_ip); parameters.put("notify_url", notify_url); String sign = createSign(characterEncoding, parameters); String param = "" + appid + " " + body + "" + mch_id + "" + " " + nonce_str + " " + notify_url + " " + out_trade_no + " " + "" + spbill_create_ip + " " + total_fee + "" + " " + trade_type + " " + sign + " "; String xmlStr = sendPost(url, param); System.out.println(xmlStr); Document document = DocumentHelper.parseText(xmlStr); // 获取根节点元素对象 Element root = document.getRootElement(); Map getstr = getElement(root); return getstr; } catch (DocumentException e) { e.printStackTrace(); } return null; } @SuppressWarnings("unchecked") private static Map getElement(Element element) { List list = element.elements(); Map map = new HashMap(); // 递归方法 for (Iterator its = list.iterator(); its.hasNext();) { Element chileEle = (Element) its.next(); map.put(chileEle.getName(), chileEle.getText()); getElement(chileEle); } return map; } /** * 微信支付签名算法sign * * @param characterEncoding * @param parameters * @return */ @SuppressWarnings("unchecked") 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=" + Key); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding) .toUpperCase(); return sign; } // 获取访问者ip @SuppressWarnings("unused") private static String getIpAddr() { String ipAddress = ""; // ipAddress = this.getRequest().getRemoteAddr(); HttpServletRequest res = ServletActionContext.getRequest(); ipAddress = res.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = res.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = res.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = res.getRemoteAddr(); if (ipAddress.equals("127.0.0.1")) { // 根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } ipAddress = inet.getHostAddress(); } } // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() // = 15 if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } return ipAddress; } /** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { String UTF8 = "UTF-8"; PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); // TODO 新添加的请求头编码 conn.setRequestProperty("Accept-Charset", "UTF-8"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(new OutputStreamWriter( conn.getOutputStream(), "utf-8")); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); // TODO 新添加设置,返回编码 in = new BufferedReader(new InputStreamReader( conn.getInputStream(), "utf-8")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } public static String getUUID() { UUID uuid = UUID.randomUUID(); String str = uuid.toString(); // 去掉"-"符号 String temp = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18); return temp; } }
原理:提交预定单:返回成功后才可以继续拼接字符串然后加密在传给前台