相比于支付宝的官方文档,我认为微信的官方文档写的就“差”多了;
其实不是微信的写的差,而是支付宝的支付代码封装的比较好,而且一下细节的东西你不仔细看很容易出错,虽然文档里面都有,但是还是有很多的坑的。每次出错总是毫无头绪,正常的错误还好,会提示到,但是签名错误,验签失败什么的,就......,不过其实认真审视流程,比对官方文档,还是能找出问题的,但就是很不爽.......。
好了,开始讲支付相关的东西。
微信支付之前,我们要先了解微信的平台,微信分为开放平台(用于app支付等功能),商户平台(用于保存商户信息,商户号,商户密钥),公众平台(公众号相关功能开发);
一定要记住一点,改版后,支付用的密钥现在都是商户密钥了(应该,反正我被坑过),商户号只能去商户平台查看。具体的配置我这里不详细讲了,网上都有,直接上代码
自定义的实体类
/**
* 微信支付自定义实体
*
* @author cdj
*/
public class WxPayModel {
/** 订单内容 */
public String body;
/** 订单编号:商户这边的编号 */
public String outTradeNo;
public String deviceInfo;
/** 币种类型:CNY */
public String feeType;
/** 交易金额:CNY */
public String totalFee;
/** ip地址:要是ipv4的不然报错 */
public String spbillCreateIp;
/** 回调地址:微信支付的回调必填 */
public String notifyUrl;
/** 交易类型:JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 */
public String tradeType;
public String productId;
public Double refundFee;
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public String getFeeType() {
return feeType;
}
public void setFeeType(String feeType) {
this.feeType = feeType;
}
public String getTotalFee() {
return totalFee;
}
public void setTotalFee(String totalFee) {
this.totalFee = totalFee;
}
public String getSpbillCreateIp() {
return spbillCreateIp;
}
public void setSpbillCreateIp(String spbillCreateIp) {
this.spbillCreateIp = spbillCreateIp;
}
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public String getTradeType() {
return tradeType;
}
public void setTradeType(String tradeType) {
this.tradeType = tradeType;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
@Override
public String toString() {
return "WxPayModel [body=" + body + ", outTradeNo=" + outTradeNo + ", deviceInfo=" + deviceInfo + ", feeType="
+ feeType + ", totalFee=" + totalFee + ", spbillCreateIp=" + spbillCreateIp + ", notifyUrl=" + notifyUrl
+ ", tradeType=" + tradeType + ", productId=" + productId + "]";
}
}
controller:
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.edgecdj.domain.JsonResult;
import com.edgecdj.paydemo.wxpay.domain.WxPayModel;
import com.edgecdj.paydemo.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;
/**
* @author cdj
* @date 2018年7月23日 下午2:17:05
*/
@RestController
@RequestMapping("/WxPay")
@Api("微信支付")
public class WxPayController {
private Log log = LogFactory.getLog(WxPayController.class);
@Autowired
WxPayService wxPayService;
@ApiOperation(value = "测试WX支付", notes = "测试WX支付")
@ApiImplicitParams({
@ApiImplicitParam(name = "wxPayModel", value = "支付对象", required = true, dataType = "WxPayModel", paramType = "body")
})
@PostMapping("/GetWxPay")
public Map
WxPayService:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.edgecdj.constant.WxPayProperties;
import com.edgecdj.paydemo.wxpay.domain.WxPayModel;
import com.edgecdj.paydemo.wxpay.service.WxPayService;
import com.edgecdj.paydemo.wxpay.utils.wxpay.PayCommonUtil2;
import com.edgecdj.paydemo.wxpay.utils.wxpay.XMLUtil;
/**
*
* @author cdj
* @date 2018年7月23日 下午2:38:32
*/
@Service
public class WxPayServiceImpl implements WxPayService {
private Log log = LogFactory.getLog(WxPayServiceImpl.class);
@Override
public Map getWxPay(WxPayModel wxPayModel, String ip) {
try {
SortedMap parameters = PayCommonUtil2.getWXPrePayID(); // 获取预付单,此处已做封装,需要工具类
parameters.put("body", wxPayModel.getBody());
parameters.put("notify_url", wxPayModel.getNotifyUrl());
parameters.put("spbill_create_ip",ip);
parameters.put("out_trade_no", wxPayModel.getOutTradeNo()); // 订单id这里我的订单id生成规则是订单id+时间
parameters.put("total_fee", wxPayModel.getTotalFee()); // 测试时,每次支付一分钱,微信支付所传的金额是以分为单位的,因此实际开发中需要x100
// 设置签名
String sign = PayCommonUtil2.createSign("UTF-8", parameters, WxPayProperties.api_key);
parameters.put("sign", sign);
// 封装请求参数结束
String requestXML = PayCommonUtil2.getRequestXml(parameters); // 获取xml结果
// 调用统一下单接口
String result = PayCommonUtil2.httpsRequest(WxPayProperties.UNIFIED_ORDER_URL, "POST",
requestXML);
System.out.println("result="+result);
SortedMap parMap = PayCommonUtil2.startWXPay(result);
parMap.put("outtradeno", wxPayModel.getOutTradeNo());
parMap.put("productId", wxPayModel.getProductId());
return parMap;
} catch (Exception e) {
e.printStackTrace();
Map errMap = new HashMap<>();
errMap.put("errMsg", e.getMessage());
return errMap;
}
}
@Override
public void weChatNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("----------------pda微信回调-------" + request);
// 读取参数
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
// 解析xml成map
Map m = new HashMap();
m = XMLUtil.doXMLParse(sb.toString());
// 过滤空 设置 TreeMap
SortedMap packageParams = new TreeMap();
Iterator it = m.keySet().iterator();
while (it.hasNext()) {
String parameter = (String) it.next();
String parameterValue = m.get(parameter);
String v = "";
if (null != parameterValue) {
v = parameterValue.trim();
}
packageParams.put(parameter, v);
}
String key = WxPayProperties.api_key; // key
// logger.info(packageParams);
// 判断签名是否正确
if (PayCommonUtil2.isTenpaySign("UTF-8", packageParams, key)) {
if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
// 这里是支付成功
// 执行自己的业务逻辑
String mch_id = (String) packageParams.get("mch_id");
// String openid = (String) packageParams.get("openid");
// String is_subscribe = (String) packageParams.get("is_subscribe");
// String out_trade_no = (String) packageParams.get("out_trade_no");
String prepay_id = (String) packageParams.get("prepay_id");
// String total_fee = (String) packageParams.get("total_fee");
log.info(JSON.toJSONString(packageParams));
// }
// to存信息
// 通知微信 预下单成功
SortedMap prepayParams = new TreeMap();
prepayParams.put("prepay_id", prepay_id);
prepayParams.put("return_code", "SUCCESS");
prepayParams.put("result_code", "SUCCESS");
String prepaySign = PayCommonUtil2.createSign("UTF-8", prepayParams, key);
prepayParams.put("sign", prepaySign);
String prepayXml = PayCommonUtil2.getRequestXml(prepayParams);
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(prepayXml.getBytes());
out.flush();
out.close();
}
}
}
}
PayCommonUtil2:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSONObject;
import com.edgecdj.constant.WxPayProperties;
import com.edgecdj.constant.WxPublicProperties;
/**
* 微信支付相关调用方法
*
* @author cdj
*/
public class PayCommonUtil2 {
public static final String TIME = "yyyyMMddHHmmss";
public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/**
* 创建微信交易对象
*/
public static SortedMap getWXPrePayID() {
SortedMap parameters = new TreeMap();
parameters.put("appid", WxPayProperties.appid);
parameters.put("mch_id", WxPayProperties.mchid);
parameters.put("nonce_str", PayCommonUtil2.CreateNoncestr());
parameters.put("fee_type", "CNY");
parameters.put("trade_type", "APP");
return parameters;
}
/**
* 创建微信公众号交易对象
*/
public static SortedMap getWXH5PrePayID() {
SortedMap parameters = new TreeMap();
parameters.put("appid", WxPublicProperties.APPID);
parameters.put("mch_id", WxPublicProperties.MCHID);
parameters.put("nonce_str", PayCommonUtil2.CreateNoncestr());
parameters.put("fee_type", "CNY");
parameters.put("trade_type", "JSAPI");
return parameters;
}
/**
* 再次签名,支付
*/
public static SortedMap startWXPay(String result) {
try {
Map map = XMLUtil.doXMLParse(result);
SortedMap parameterMap = new TreeMap();
parameterMap.put("appid", WxPayProperties.appid);
parameterMap.put("partnerid", WxPayProperties.mchid);
parameterMap.put("prepayid", map.get("prepay_id"));
parameterMap.put("package", "Sign=WXPay");
parameterMap.put("noncestr", PayCommonUtil2.CreateNoncestr());
// 本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下
parameterMap.put("timestamp",
Long.parseLong(String.valueOf(System.currentTimeMillis()).toString().substring(0, 10)));
String sign = PayCommonUtil2.createSign("UTF-8", parameterMap, WxPayProperties.api_key);
parameterMap.put("sign", sign);
return parameterMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* H5再次签名,支付
*/
public static SortedMap startWXH5Pay(String result) {
try {
Map map = XMLUtil.doXMLParse(result);
SortedMap parameterMap = new TreeMap();
parameterMap.put("appId", WxPublicProperties.APPID);// 这里注意一下,appId是大写的I
parameterMap.put("nonceStr", PayCommonUtil2.CreateNoncestr());
parameterMap.put("package", "prepay_id=" + map.get("prepay_id"));
parameterMap.put("signType", "MD5");
// 本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下
parameterMap.put("timeStamp", String.valueOf(System.currentTimeMillis()).toString().substring(0, 10));
// H5的签名的密钥不同
String sign = PayCommonUtil2.createSign("UTF-8", parameterMap, WxPublicProperties.MCHKEY);
parameterMap.put("paySign", sign);
return parameterMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 创建随机数
*
* @param length
* @return
*/
public static String CreateNoncestr() {
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String res = "";
for (int i = 0; i < 16; i++) {
Random rd = new Random();
res += chars.charAt(rd.nextInt(chars.length() - 1));
}
return res;
}
/**
* 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
*
* @return boolean
*/
public static boolean isTenpaySign(String characterEncoding, SortedMap packageParams, String key) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
// sb.append("key=" + WxPayProperties.api_key);
sb.append("key=" + key);
// 算出摘要
String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
String tenpaySign = ((String) packageParams.get("sign")).toLowerCase();
// System.out.println(tenpaySign + " " + mysign);
return tenpaySign.equals(mysign);
}
/**
* @Description:创建sign签名
* @param characterEncoding
* 编码格式
* @param parameters
* 请求参数
* @return
*/
public static String createSign(String characterEncoding, SortedMap parameters, String key) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
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;
}
/**
* @Description:将请求参数转换为xml格式的string
* @param parameters
* 请求参数
* @return
*/
public static String getRequestXml(SortedMap parameters) {
StringBuffer sb = new StringBuffer();
sb.append("");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "" + k + ">");
} else {
sb.append("<" + k + ">" + v + "" + k + ">");
}
}
sb.append(" ");
return sb.toString();
}
/**
* @Description:返回给微信的参数
* @param return_code
* 返回编码
* @param return_msg
* 返回信息
* @return
*/
public static String setXML(String return_code, String return_msg) {
return " ";
}
/**
* 发送https请求
*
* @param requestUrl
* 请求地址
* @param requestMethod
* 请求方式(GET、POST)
* @param outputStr
* 提交的数据
* @return 返回微信服务器响应的信息
*/
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
// conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
return buffer.toString();
} catch (ConnectException ce) {
// log.error("连接超时:{}", ce);
} catch (Exception e) {
// log.error("https请求异常:{}", e);
}
return null;
}
/**
* 发送https请求
*
* @param requestUrl
* 请求地址
* @param requestMethod
* 请求方式(GET、POST)
* @param outputStr
* 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod) {
JSONObject jsonObject = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
// conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(3000);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
// conn.setRequestProperty("content-type",
// "application/x-www-form-urlencoded");
// 当outputStr不为null时向输出流写数据
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = JSONObject.parseObject(buffer.toString());
} catch (ConnectException ce) {
// log.error("连接超时:{}", ce);
} catch (Exception e) {
System.out.println(e);
// log.error("https请求异常:{}", e);
}
return jsonObject;
}
public static String urlEncodeUTF8(String source) {
String result = source;
try {
result = java.net.URLEncoder.encode(source, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 接收微信的异步通知
*
* @throws IOException
*/
public static String reciverWx(HttpServletRequest request) throws IOException {
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
return sb.toString();
}
/**
* 产生num位的随机数
*
* @return
*/
public static String getRandByNum(int num) {
String length = "1";
for (int i = 0; i < num; i++) {
length += "0";
}
Random rad = new Random();
String result = rad.nextInt(Integer.parseInt(length)) + "";
if (result.length() != num) {
return getRandByNum(num);
}
return result;
}
/**
* 返回当前时间字符串
*
* @return yyyyMMddHHmmss
*/
public static String getDateStr() {
SimpleDateFormat sdf = new SimpleDateFormat(TIME);
return sdf.format(new Date());
}
/**
* 将日志保存至指定路径
*
* @param path
* @param str
*/
public static void saveLog(String path, String str) {
File file = new File(path);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path);
fos.write(str.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void saveE(String path, Exception exception) {
try {
int i = 1 / 0;
} catch (final Exception e) {
try {
new PrintWriter(new BufferedWriter(new FileWriter(path, true)), true).println(new Object() {
public String toString() {
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter);
e.printStackTrace(writer);
StringBuffer buffer = stringWriter.getBuffer();
return buffer.toString();
}
});
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
MD5Util
import java.security.MessageDigest;
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" };
}
MyX509TrustManager:
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
public class MyX509TrustManager implements TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
XMLUtil:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class XMLUtil {
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map doXMLParse(String strxml) throws JDOMException, IOException {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
if(null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
}
m.put(k, v);
}
//关闭流
in.close();
return m;
}
/**
* 获取子结点的xml
* @param children
* @return String
*/
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if(!children.isEmpty()) {
Iterator it = children.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if(!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("" + name + ">");
}
}
return sb.toString();
}
}
利用swagger 进行测试
得到结果:
app端通过这次参数调用微信sdk方法,可以进行微信支付