diff --git a/mallinkService/pom.xml b/mallinkService/pom.xml
index 47ddf2151..cccc06ba6 100644
--- a/mallinkService/pom.xml
+++ b/mallinkService/pom.xml
@@ -10,4 +10,19 @@
4.0.0
mallinkService
+
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ 3.11.0
+
+
+
+ org.dom4j
+ dom4j
+ 2.1.1
+
+
\ No newline at end of file
diff --git a/mallinkService/src/main/java/com/simple/pay/WxPay.java b/mallinkService/src/main/java/com/simple/pay/WxPay.java
new file mode 100644
index 000000000..033cd9ecd
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/pay/WxPay.java
@@ -0,0 +1,287 @@
+package com.simple.pay;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.simple.utils.HttpUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxPay {
+ protected static Logger log = LoggerFactory.getLogger(WxPay.class);
+
+ // 统一下单接口
+ private static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+ // 订单查询
+ private static final String ORDERQUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
+ // 关闭订单
+ private static final String CLOSEORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
+ // 撤销订单
+ private static final String REVERSE_URL = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
+ // 申请退款
+ private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+ // 查询退款
+ private static final String REFUNDQUERY_URL = "https://api.mch.weixin.qq.com/pay/refundquery";
+ // 下载对账单
+ private static final String DOWNLOADBILLY_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
+ // 交易保障
+ private static final String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report";
+ // 转换短链接
+ private static final String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl";
+ // 授权码查询openId接口
+ private static final String AUTHCODETOOPENID_URL = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
+ // 刷卡支付
+ private static final String MICROPAY_URL = "https://api.mch.weixin.qq.com/pay/micropay";
+ // 企业付款
+ private static final String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
+ // 查询企业付款
+ private static final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo";
+
+ private WxPay() {
+ }
+
+ /**
+ * 交易类型枚举
+ *
+ * @author Javen 2017年4月15日
+ * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
+ * MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口
+ */
+ public static enum TradeType {
+ JSAPI, NATIVE, APP, WAP, MICROPAY
+ }
+
+ /**
+ * 统一下单
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_1
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
+ *
+ * @param params
+ * @return
+ */
+ public static String pushOrder(Map params) {
+ return doPost(UNIFIEDORDER_URL, params);
+ }
+
+ /**
+ * 订单查询
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_2
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String orderQuery(Map params) {
+ return doPost(ORDERQUERY_URL, params);
+ }
+
+ /**
+ * 关闭订单
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_3
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
+ *
+ * @param params
+ * @return
+ */
+ public static String closeOrder(Map params) {
+ return doPost(CLOSEORDER_URL, params);
+ }
+
+ /**
+ * 撤销订单
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_11&index=3
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
+ *
+ * @param params
+ * 请求参数
+ * @param certPath
+ * 证书文件目录
+ * @param certPass
+ * 证书密码
+ * @return
+ */
+ public static String orderReverse(Map params, String certPath, String certPass) {
+ return doPostSSL(REVERSE_URL, params, certPath, certPass);
+ }
+
+ /**
+ * 申请退款
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_4
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4
+ *
+ * @param params
+ * 请求参数
+ * @param certPath
+ * 证书文件目录
+ * @param certPass
+ * 证书密码
+ * @return
+ */
+ public static String orderRefund(Map params, String certPath, String certPass) {
+ return doPostSSL(REFUND_URL, params, certPath, certPass);
+ }
+
+ /**
+ * 查询退款
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_5
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String orderRefundQuery(Map params) {
+ return doPost(REFUNDQUERY_URL, params);
+ }
+
+ /**
+ * 下载对账单
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_6
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_6
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String downloadBill(Map params) {
+ return doPost(DOWNLOADBILLY_URL, params);
+ }
+
+ /**
+ * 交易保障
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_14&index=7
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_14&index=7
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String orderReport(Map params) {
+ return doPost(REPORT_URL, params);
+ }
+
+ /**
+ * 转换短链接
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_9&index=8
+ * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String toShortUrl(Map params) {
+ return doPost(SHORT_URL, params);
+ }
+
+ /**
+ * 授权码查询openId
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_12&index=9
+ * 商户模式接入文档:
+ * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String authCodeToOpenid(Map params) {
+ return doPost(AUTHCODETOOPENID_URL, params);
+ }
+
+ /**
+ * 刷卡支付
+ * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_10&index=1
+ * 商户模式接入文档:
+ * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
+ *
+ * @param params
+ * 请求参数
+ * @return
+ */
+ public static String micropay(Map params) {
+ return WxPay.doPost(MICROPAY_URL, params);
+ }
+
+ /**
+ * 企业付款
+ *
+ * @param params
+ * 请求参数
+ * @param certPath
+ * 证书文件目录
+ * @param certPassword
+ * 证书密码
+ * @return {String}
+ */
+ public static String transfers(Map params, String certPath, String certPassword) {
+ return WxPay.doPostSSL(TRANSFERS_URL, params, certPath, certPassword);
+ }
+
+ /**
+ * 查询企业付款
+ *
+ * @param params
+ * 请求参数
+ * @param certPath
+ * 证书文件目录
+ * @param certPassword
+ * 证书密码
+ * @return {String}
+ */
+ public static String getTransferInfo(Map params, String certPath, String certPassword) {
+ return WxPay.doPostSSL(GETTRANSFERINFO_URL, params, certPath, certPassword);
+ }
+
+ /**
+ * 商户模式下 扫码模式一之生成二维码
+ *
+ * @param appid
+ * @param mch_id
+ * @param product_id
+ * @param partnerKey
+ * @param isToShortUrl
+ * 是否转化为短连接
+ * @return
+ */
+ public static String getCodeUrl(String appid, String mch_id, String product_id, String partnerKey,
+ boolean isToShortUrl) {
+ String url = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX";
+ String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
+ String nonceStr = Long.toString(System.currentTimeMillis());
+ Map packageParams = new HashMap();
+ packageParams.put("appid", appid);
+ packageParams.put("mch_id", mch_id);
+ packageParams.put("product_id", product_id);
+ packageParams.put("time_stamp", timeStamp);
+ packageParams.put("nonce_str", nonceStr);
+ String packageSign = WxPayment.createSign(packageParams, partnerKey);
+ String qrCodeUrl = WxPayment.replace(url, "XXXXX", packageSign, appid, mch_id, product_id, timeStamp,
+ nonceStr);
+ if (isToShortUrl) {
+ String shortResult = WxPay
+ .toShortUrl(WxPayment.buildShortUrlParasMap(appid, null, mch_id, null, qrCodeUrl, partnerKey));
+
+ if (log.isDebugEnabled()) {
+ log.info(shortResult);
+ }
+ Map shortMap = WxPayment.xmlToMap(shortResult);
+ String return_code = shortMap.get("return_code");
+ if (WxPayment.codeIsOK(return_code)) {
+ String result_code = shortMap.get("result_code");
+ if (WxPayment.codeIsOK(result_code)) {
+ qrCodeUrl = shortMap.get("short_url");
+ }
+ }
+ }
+
+ return qrCodeUrl;
+ }
+
+ public static String doPost(String url, Map params) {
+ return HttpUtil.payPost(url, WxPayment.toXml(params));
+ }
+
+ public static String doPostSSL(String url, Map params, String certPath, String certPass) {
+ return HttpUtil.payPostSSL(url, WxPayment.toXml(params), certPath, certPass);
+ }
+}
diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayOrder.java b/mallinkService/src/main/java/com/simple/pay/WxPayOrder.java
new file mode 100644
index 000000000..133fc2287
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/pay/WxPayOrder.java
@@ -0,0 +1,154 @@
+package com.simple.pay;
+
+/**
+ * Created by fanglong on 2017/8/14.
+ */
+public class WxPayOrder {
+ private String appid; // 公众账号ID
+ private String mch_id; // 商户号
+ private String nonce_str; // 随机字符串
+ private String sign; // 签名
+ private String body; // 商品简单描述 128
+ private String out_trade_no; // 商户订单号
+ private Integer total_fee; // 支付金额
+ private String spbill_create_ip; // 支付IP
+ private String notify_url; // 通知地址
+ private String trade_type; // 支付类型
+ private String product_id; // 商品ID - 扫码必传
+ private String time_start; // 开始时间
+ private String time_expire; // 失效时间
+ private String openid; // openId
+
+ public String getTime_start() {
+ return time_start;
+ }
+
+ public void setTime_start(String time_start) {
+ this.time_start = time_start;
+ }
+
+ public String getTime_expire() {
+ return time_expire;
+ }
+
+ public void setTime_expire(String time_expire) {
+ this.time_expire = time_expire;
+ }
+
+ public String getAppid() {
+ return appid;
+ }
+
+ public void setAppid(String appid) {
+ this.appid = appid;
+ }
+
+ public String getMch_id() {
+ return mch_id;
+ }
+
+ public void setMch_id(String mch_id) {
+ this.mch_id = mch_id;
+ }
+
+ public String getNonce_str() {
+ return nonce_str;
+ }
+
+ public void setNonce_str(String nonce_str) {
+ this.nonce_str = nonce_str;
+ }
+
+ public String getSign() {
+ return sign;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public String getOut_trade_no() {
+ return out_trade_no;
+ }
+
+ public void setOut_trade_no(String out_trade_no) {
+ this.out_trade_no = out_trade_no;
+ }
+
+ public Integer getTotal_fee() {
+ return total_fee;
+ }
+
+ public void setTotal_fee(Integer total_fee) {
+ this.total_fee = total_fee;
+ }
+
+ public String getSpbill_create_ip() {
+ return spbill_create_ip;
+ }
+
+ public void setSpbill_create_ip(String spbill_create_ip) {
+ this.spbill_create_ip = spbill_create_ip;
+ }
+
+ public String getNotify_url() {
+ return notify_url;
+ }
+
+ public void setNotify_url(String notify_url) {
+ this.notify_url = notify_url;
+ }
+
+ public String getTrade_type() {
+ return trade_type;
+ }
+
+ public void setTrade_type(String trade_type) {
+ this.trade_type = trade_type;
+ }
+
+ public String getProduct_id() {
+ return product_id;
+ }
+
+ public void setProduct_id(String product_id) {
+ this.product_id = product_id;
+ }
+
+ public String getOpenid() {
+ return openid;
+ }
+
+ public void setOpenid(String openid) {
+ this.openid = openid;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("WxPayOrder{");
+ sb.append("appid='").append(appid).append('\'');
+ sb.append(", mch_id='").append(mch_id).append('\'');
+ sb.append(", nonce_str='").append(nonce_str).append('\'');
+ sb.append(", sign='").append(sign).append('\'');
+ sb.append(", body='").append(body).append('\'');
+ sb.append(", out_trade_no='").append(out_trade_no).append('\'');
+ sb.append(", total_fee=").append(total_fee);
+ sb.append(", spbill_create_ip='").append(spbill_create_ip).append('\'');
+ sb.append(", notify_url='").append(notify_url).append('\'');
+ sb.append(", trade_type='").append(trade_type).append('\'');
+ sb.append(", product_id='").append(product_id).append('\'');
+ sb.append(", time_start='").append(time_start).append('\'');
+ sb.append(", time_expire='").append(time_expire).append('\'');
+ sb.append(", openid='").append(openid).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/mallinkService/src/main/java/com/simple/pay/WxPayment.java b/mallinkService/src/main/java/com/simple/pay/WxPayment.java
new file mode 100644
index 000000000..e0739d84c
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/pay/WxPayment.java
@@ -0,0 +1,313 @@
+package com.simple.pay;
+
+import com.simple.utils.HashUtil;
+import com.simple.utils.Utility;
+import com.simple.utils.XmlUtil;
+import org.apache.commons.codec.Charsets;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+public class WxPayment {
+ /**
+ * 构建参数
+ *
+ * @param appid
+ * @param sub_appid
+ * @param mch_id
+ * @param sub_mch_id
+ * @param device_info
+ * @param body
+ * @param detail
+ * @param attach
+ * @param out_trade_no
+ * @param total_fee
+ * @param spbill_create_ip
+ * @param auth_code
+ * @param paternerKey
+ * @return
+ */
+ public static Map buildParasMap(String appid, String sub_appid, String mch_id, String sub_mch_id,
+ String device_info, String body, String detail, String attach, String out_trade_no, String total_fee,
+ String spbill_create_ip, String auth_code, String paternerKey) {
+ Map queryParas = new HashMap();
+ queryParas.put("appid", appid);
+ queryParas.put("sub_appid", sub_appid);
+ queryParas.put("mch_id", mch_id);
+ queryParas.put("sub_mch_id", sub_mch_id);
+ queryParas.put("device_info", device_info);
+ queryParas.put("nonce_str", String.valueOf(System.currentTimeMillis()));
+ queryParas.put("body", body);
+ queryParas.put("detail", detail);
+ queryParas.put("attach", attach);
+ queryParas.put("out_trade_no", out_trade_no);
+ queryParas.put("total_fee", total_fee);
+ queryParas.put("spbill_create_ip", spbill_create_ip);
+ queryParas.put("auth_code", auth_code);
+ String sign = WxPayment.createSign(queryParas, paternerKey);
+ queryParas.put("sign", sign);
+ return queryParas;
+ }
+
+ /**
+ * 封装查询请求参数 参考代码
+ *
+ * @param appid
+ * @param sub_appid
+ * @param mch_id
+ * @param sub_mch_id
+ * @param transaction_id
+ * @param out_trade_no
+ * @param paternerKey
+ * @return
+ */
+ public static Map buildParasMap(String appid, String sub_appid, String mch_id, String sub_mch_id,
+ String transaction_id, String out_trade_no, String paternerKey) {
+ Map params = new HashMap();
+
+ params.put("appid", appid);
+ params.put("sub_appid", sub_appid);
+ params.put("mch_id", mch_id);
+ params.put("sub_mch_id", sub_mch_id);
+ params.put("transaction_id", transaction_id);
+ params.put("out_trade_no", out_trade_no);
+
+ return buildSignAfterParasMap(params, paternerKey);
+ }
+
+ /**
+ * 构建统一下单参数
+ *
+ * @param appid
+ * @param sub_appid
+ * 否
+ * @param mch_id
+ * @param sub_mch_id
+ * 服务商模式下必须
+ * @param device_info
+ * 否
+ * @param body
+ * @param detail
+ * 否
+ * @param attach
+ * 否
+ * @param out_trade_no
+ * @param total_fee
+ * @param spbill_create_ip
+ * @param paternerKey
+ * @param notify_url
+ * @param trade_type
+ * @param product_id
+ * 扫码支付必传
+ * @return
+ */
+ public static Map buildUnifiedOrderParasMap(String appid, String sub_appid, String mch_id,
+ String sub_mch_id, String device_info, String body, String detail, String attach, String out_trade_no,
+ String total_fee, String spbill_create_ip, String notify_url, String trade_type, String paternerKey,
+ String product_id) {
+ Map params = new HashMap();
+ params.put("appid", appid);
+ params.put("sub_appid", sub_appid);
+ params.put("mch_id", mch_id);
+ params.put("sub_mch_id", sub_mch_id);
+ params.put("device_info", device_info);
+ params.put("body", body);
+ params.put("detail", detail);
+ params.put("attach", attach);
+
+ params.put("total_fee", total_fee);
+ params.put("spbill_create_ip", spbill_create_ip);
+ params.put("notify_url", notify_url);
+ params.put("trade_type", trade_type);
+ params.put("product_id", product_id);
+
+ return buildSignAfterParasMap(params, paternerKey);
+ }
+
+ /**
+ * 构建短链接参数
+ *
+ * @param appid
+ * @param sub_appid
+ * @param mch_id
+ * @param sub_mch_id
+ * @param long_url
+ * @param paternerKey
+ * @return
+ */
+ public static Map buildShortUrlParasMap(String appid, String sub_appid, String mch_id,
+ String sub_mch_id, String long_url, String paternerKey) {
+ Map params = new HashMap();
+ params.put("appid", appid);
+ params.put("sub_appid", sub_appid);
+ params.put("mch_id", mch_id);
+ params.put("sub_mch_id", sub_mch_id);
+ params.put("long_url", long_url);
+
+ return buildSignAfterParasMap(params, paternerKey);
+
+ }
+
+ /**
+ * 组装签名的字段
+ *
+ * @param params
+ * 参数
+ * @param urlEncoder
+ * 是否urlEncoder
+ * @return String
+ */
+ public static String packageSign(Map params, boolean urlEncoder) {
+ // 先将参数以其参数名的字典序升序进行排序
+ TreeMap sortedParams = new TreeMap(params);
+ // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (Entry param : sortedParams.entrySet()) {
+ String value = param.getValue();
+ if (StringUtils.isBlank(value)) {
+ continue;
+ }
+ if (first) {
+ first = false;
+ } else {
+ sb.append("&");
+ }
+ sb.append(param.getKey()).append("=");
+ if (urlEncoder) {
+ try {
+ value = urlEncode(value);
+ } catch (UnsupportedEncodingException e) {
+ }
+ }
+ sb.append(value);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * urlEncode
+ *
+ * @param src
+ * 微信参数
+ * @return String
+ * @throws UnsupportedEncodingException
+ * 编码错误
+ */
+ public static String urlEncode(String src) throws UnsupportedEncodingException {
+ return URLEncoder.encode(src, Charsets.UTF_8.name()).replace("+", "%20");
+ }
+
+ /**
+ * 构建签名之后的参数
+ *
+ * @param params
+ * @param paternerKey
+ * @return Map
+ */
+ public static Map buildSignAfterParasMap(Map params, String paternerKey) {
+ params.put("nonce_str", Utility.generateUUID().replace("-", ""));
+ String sign = WxPayment.createSign(params, paternerKey);
+ params.put("sign", sign);
+ return params;
+ }
+
+ /**
+ * 生成签名
+ *
+ * @param params
+ * 参数
+ * @param partnerKey
+ * 支付密钥
+ * @return sign
+ */
+ public static String createSign(Map params, String partnerKey) {
+ // 生成签名前先去除sign
+ params.remove("sign");
+ String stringA = packageSign(params, false);
+ String stringSignTemp = stringA + "&key=" + partnerKey;
+ return HashUtil.md5(stringSignTemp).toUpperCase();
+ }
+
+ /**
+ * 支付异步通知时校验sign
+ *
+ * @param params
+ * 参数
+ * @param paternerKey
+ * 支付密钥
+ * @return {boolean}
+ */
+ public static boolean verifyNotify(Map params, String paternerKey) {
+ String sign = params.get("sign");
+ String localSign = WxPayment.createSign(params, paternerKey);
+ return sign.equals(localSign);
+ }
+
+ /**
+ * 判断接口返回的code是否是SUCCESS
+ *
+ * @param return_code、result_code
+ * @return
+ */
+ public static boolean codeIsOK(String return_code) {
+ return StringUtils.isNotBlank(return_code) && "SUCCESS".equals(return_code);
+ }
+
+ /**
+ * 微信下单map to xml
+ *
+ * @param params
+ * 参数
+ * @return String
+ */
+ public static String toXml(Map params) {
+ StringBuilder xml = new StringBuilder();
+ xml.append("");
+ for (Entry entry : params.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ // 略过空值
+ if (StringUtils.isBlank(value))
+ continue;
+ xml.append("<").append(key).append(">");
+ xml.append(entry.getValue());
+ xml.append("").append(key).append(">");
+ }
+ xml.append("");
+ return xml.toString();
+ }
+
+ /**
+ * 针对支付的xml,没有嵌套节点的简单处理
+ *
+ * @param xmlStr
+ * xml字符串
+ * @return map集合
+ */
+ @SuppressWarnings("unchecked")
+ public static Map xmlToMap(String xmlStr) {
+ return XmlUtil.parseXml2Map(xmlStr);
+ }
+
+ /**
+ * 替换url中的参数
+ *
+ * @param str
+ * @param regex
+ * @param args
+ * @return
+ */
+ public static String replace(String str, String regex, String... args) {
+ int length = args.length;
+ for (int i = 0; i < length; i++) {
+ str = str.replaceFirst(regex, args[i]);
+ }
+ return str;
+ }
+}
diff --git a/mallinkService/src/main/java/com/simple/utils/DataUtil.java b/mallinkService/src/main/java/com/simple/utils/DataUtil.java
new file mode 100644
index 000000000..f3a3c6847
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/utils/DataUtil.java
@@ -0,0 +1,258 @@
+package com.simple.utils;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 常见的辅助类
+ *
+ * @author Stormeye
+ * @since 2011-11-08
+ */
+public final class DataUtil {
+ private DataUtil() {
+ }
+
+ /**
+ * 十进制字节数组转十六进制字符串
+ *
+ * @param b
+ * @return
+ */
+ public static final String byte2hex(byte[] b) { // 一个字节数,转成16进制字符串
+ StringBuilder hs = new StringBuilder(b.length * 2);
+ String stmp = "";
+ for (int n = 0; n < b.length; n++) {
+ // 整数转成十六进制表示
+ stmp = Integer.toHexString(b[n] & 0XFF);
+ if (stmp.length() == 1)
+ hs.append("0").append(stmp);
+ else
+ hs.append(stmp);
+ }
+ return hs.toString(); // 转成大写
+ }
+
+ /**
+ * 十六进制字符串转十进制字节数组
+ *
+ * @param hs
+ * @return
+ */
+ public static final byte[] hex2byte(String hs) {
+ byte[] b = hs.getBytes();
+ if ((b.length % 2) != 0)
+ throw new IllegalArgumentException("长度不是偶数");
+ byte[] b2 = new byte[b.length / 2];
+ for (int n = 0; n < b.length; n += 2) {
+ String item = new String(b, n, 2);
+ // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个十进制字节
+ b2[n / 2] = (byte) Integer.parseInt(item, 16);
+ }
+ return b2;
+ }
+
+ /**
+ * 这个方法可以通过与某个类的class文件的相对路径来获取文件或目录的绝对路径。 通常在程序中很难定位某个相对路径,特别是在B/S应用中。
+ * 通过这个方法,我们可以根据我们程序自身的类文件的位置来定位某个相对路径。
+ * 比如:某个txt文件相对于程序的Test类文件的路径是../../resource/test.txt,
+ * 那么使用本方法Path.getFullPathRelateClass("../../resource/test.txt",Test.class)
+ * 得到的结果是txt文件的在系统中的绝对路径。
+ *
+ * @param relatedPath 相对路径
+ * @param cls 用来定位的类
+ * @return 相对路径所对应的绝对路径
+ * @throws IOException 因为本方法将查询文件系统,所以可能抛出IO异常
+ */
+ public static final String getFullPathRelateClass(String relatedPath, Class> cls) {
+ String path = null;
+ if (relatedPath == null) {
+ throw new NullPointerException();
+ }
+ String clsPath = getPathFromClass(cls);
+ File clsFile = new File(clsPath);
+ String tempPath = clsFile.getParent() + File.separator + relatedPath;
+ File file = new File(tempPath);
+ try {
+ path = file.getCanonicalPath();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return path;
+ }
+
+ /**
+ * 获取class文件所在绝对路径
+ *
+ * @param cls
+ * @return
+ * @throws IOException
+ */
+ public static final String getPathFromClass(Class> cls) {
+ String path = null;
+ if (cls == null) {
+ throw new NullPointerException();
+ }
+ URL url = getClassLocationURL(cls);
+ if (url != null) {
+ path = url.getPath();
+ if ("jar".equalsIgnoreCase(url.getProtocol())) {
+ try {
+ path = new URL(path).getPath();
+ } catch (MalformedURLException e) {
+ }
+ int location = path.indexOf("!/");
+ if (location != -1) {
+ path = path.substring(0, location);
+ }
+ }
+ File file = new File(path);
+ try {
+ path = file.getCanonicalPath();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return path;
+ }
+
+ /**
+ * 判断对象是否Empty(null或元素为0)
+ * 实用于对如下对象做判断:String Collection及其子类 Map及其子类
+ *
+ * @param pObj 待检查对象
+ * @return boolean 返回的布尔值
+ */
+ public static final boolean isEmpty(Object pObj) {
+ if (pObj == null)
+ return true;
+ if (pObj == "")
+ return true;
+ if (pObj instanceof String) {
+ if (((String) pObj).trim().length() == 0) {
+ return true;
+ }
+ } else if (pObj instanceof Collection>) {
+ if (((Collection>) pObj).size() == 0) {
+ return true;
+ }
+ } else if (pObj instanceof Map, ?>) {
+ if (((Map, ?>) pObj).size() == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 判断对象是否为NotEmpty(!null或元素>0)
+ * 实用于对如下对象做判断:String Collection及其子类 Map及其子类
+ *
+ * @param pObj 待检查对象
+ * @return boolean 返回的布尔值
+ */
+ public static final boolean isNotEmpty(Object pObj) {
+ if (pObj == null)
+ return false;
+ if (pObj == "")
+ return false;
+ if (pObj instanceof String) {
+ if (((String) pObj).trim().length() == 0) {
+ return false;
+ }
+ } else if (pObj instanceof Collection>) {
+ if (((Collection>) pObj).size() == 0) {
+ return false;
+ }
+ } else if (pObj instanceof Map, ?>) {
+ if (((Map, ?>) pObj).size() == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * JS输出含有\n的特殊处理
+ *
+ * @param pStr
+ * @return
+ */
+ public static final String replace4JsOutput(String pStr) {
+ pStr = pStr.replace("\r\n", "
");
+ pStr = pStr.replace("\t", " ");
+ pStr = pStr.replace(" ", " ");
+ return pStr;
+ }
+
+ /**
+ * 分别去空格
+ *
+ * @param paramArray
+ * @return
+ */
+ public static final String[] trim(String[] paramArray) {
+ if (ArrayUtils.isEmpty(paramArray)) {
+ return paramArray;
+ }
+ String[] resultArray = new String[paramArray.length];
+ for (int i = 0; i < paramArray.length; i++) {
+ String param = paramArray[i];
+ resultArray[i] = StringUtils.trim(param);
+ }
+ return resultArray;
+ }
+
+ /**
+ * 获取类的class文件位置的URL
+ *
+ * @param cls
+ * @return
+ */
+ private static URL getClassLocationURL(final Class> cls) {
+ if (cls == null)
+ throw new IllegalArgumentException("null input: cls");
+ URL result = null;
+ final String clsAsResource = cls.getName().replace('.', '/').concat(".class");
+ final ProtectionDomain pd = cls.getProtectionDomain();
+ if (pd != null) {
+ final CodeSource cs = pd.getCodeSource();
+ if (cs != null)
+ result = cs.getLocation();
+ if (result != null) {
+ if ("file".equals(result.getProtocol())) {
+ try {
+ if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip"))
+ result = new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clsAsResource));
+ else if (new File(result.getFile()).isDirectory())
+ result = new URL(result, clsAsResource);
+ } catch (MalformedURLException ignore) {
+ }
+ }
+ }
+ }
+ if (result == null) {
+ final ClassLoader clsLoader = cls.getClassLoader();
+ result = clsLoader != null ? clsLoader.getResource(clsAsResource)
+ : ClassLoader.getSystemResource(clsAsResource);
+ }
+ return result;
+ }
+
+ /** 初始化设置默认值 */
+ public static final K ifNull(K k, K defaultValue) {
+ if (k == null) {
+ return defaultValue;
+ }
+ return k;
+ }
+}
\ No newline at end of file
diff --git a/mallinkService/src/main/java/com/simple/utils/HashUtil.java b/mallinkService/src/main/java/com/simple/utils/HashUtil.java
new file mode 100644
index 000000000..ae7d5c8f2
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/utils/HashUtil.java
@@ -0,0 +1,85 @@
+package com.simple.utils;
+
+import java.security.MessageDigest;
+
+/**
+ * @author Stormeye
+ * @since 2018.08.09
+ */
+public class HashUtil {
+ private static final java.security.SecureRandom random = new java.security.SecureRandom();
+ private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
+ private static final char[] CHAR_ARRAY = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ .toCharArray();
+
+ public static String md5(String srcStr) {
+ return hash("MD5", srcStr);
+ }
+
+ public static String sha1(String srcStr) {
+ return hash("SHA-1", srcStr);
+ }
+
+ public static String sha256(String srcStr) {
+ return hash("SHA-256", srcStr);
+ }
+
+ public static String sha384(String srcStr) {
+ return hash("SHA-384", srcStr);
+ }
+
+ public static String sha512(String srcStr) {
+ return hash("SHA-512", srcStr);
+ }
+
+ public static String hash(String algorithm, String srcStr) {
+ try {
+ MessageDigest md = MessageDigest.getInstance(algorithm);
+ byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
+ return toHex(bytes);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static String toHex(byte[] bytes) {
+ StringBuilder ret = new StringBuilder(bytes.length * 2);
+ for (int i = 0; i < bytes.length; i++) {
+ ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
+ ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
+ }
+ return ret.toString();
+ }
+
+ /**
+ * md5 128bit 16bytes sha1 160bit 20bytes sha256 256bit 32bytes sha384
+ * 384bit 48bytes sha512 512bit 64bytes
+ */
+ public static String generateSalt(int saltLength) {
+ StringBuilder salt = new StringBuilder();
+ for (int i = 0; i < saltLength; i++) {
+ salt.append(CHAR_ARRAY[random.nextInt(CHAR_ARRAY.length)]);
+ }
+ return salt.toString();
+ }
+
+ public static String generateSaltForSha256() {
+ return generateSalt(32);
+ }
+
+ public static String generateSaltForSha512() {
+ return generateSalt(64);
+ }
+
+ public static boolean slowEquals(byte[] a, byte[] b) {
+ if (a == null || b == null) {
+ return false;
+ }
+
+ int diff = a.length ^ b.length;
+ for (int i = 0; i < a.length && i < b.length; i++) {
+ diff |= a[i] ^ b[i];
+ }
+ return diff == 0;
+ }
+}
diff --git a/mallinkService/src/main/java/com/simple/utils/HttpUtil.java b/mallinkService/src/main/java/com/simple/utils/HttpUtil.java
index 3959d1eba..35e54cd43 100644
--- a/mallinkService/src/main/java/com/simple/utils/HttpUtil.java
+++ b/mallinkService/src/main/java/com/simple/utils/HttpUtil.java
@@ -1,23 +1,32 @@
package com.simple.utils;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.apache.commons.codec.Charsets;
+import org.apache.commons.io.IOUtils;
import org.apache.http.*;
-import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import java.io.*;
import java.net.URI;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -34,13 +43,17 @@ public class HttpUtil {
private static Logger logger = Logger.getLogger(String.valueOf(HttpUtil.class));
+ private static final MediaType CONTENT_TYPE_FORM = MediaType.parse("application/x-www-form-urlencoded");
+ private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
+
+
/**
* get请求
* @return
*/
public static String doGet(String url) {
try {
- HttpClient client = new DefaultHttpClient();
+ CloseableHttpClient client = HttpClients.createDefault();
//发送get请求
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
@@ -71,7 +84,7 @@ public class HttpUtil {
BufferedReader in = null;
try {
// 定义HttpClient
- HttpClient client = new DefaultHttpClient();
+ CloseableHttpClient client = HttpClients.createDefault();
// 实例化HTTP方法
HttpPost request = new HttpPost();
request.setURI(new URI(url));
@@ -163,5 +176,84 @@ public class HttpUtil {
return null;
}
+
+ public static String payPost(String url, String params) {
+ RequestBody body = RequestBody.create(CONTENT_TYPE_FORM, params);
+
+ Request request = null;
+ try {
+ request = new Request.Builder().addHeader("Accept-Charset", "utf-8")
+ .addHeader("Content-Type", "application/x-www-form-urlencoded")
+ .addHeader("Content-Length", String.valueOf(body.contentLength()))
+ .url(url).post(body).build();
+ return exec(request);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ private static String exec(okhttp3.Request request) {
+ try {
+ okhttp3.Response response = new OkHttpClient().newCall(request).execute();
+ if (!response.isSuccessful())
+ throw new RuntimeException("Unexpected code " + response);
+ return response.body().string();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String payPostSSL(String url, String data, String certPath, String certPass) {
+ HttpsURLConnection conn = null;
+ OutputStream out = null;
+ InputStream inputStream = null;
+ BufferedReader reader = null;
+ try {
+ KeyStore clientStore = KeyStore.getInstance("PKCS12");
+ clientStore.load(new FileInputStream(certPath), certPass.toCharArray());
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(clientStore, certPass.toCharArray());
+ KeyManager[] kms = kmf.getKeyManagers();
+ SSLContext sslContext = SSLContext.getInstance("TLSv1");
+
+ sslContext.init(kms, null, new SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
+ URL _url = new URL(url);
+ conn = (HttpsURLConnection) _url.openConnection();
+
+ conn.setConnectTimeout(25000);
+ conn.setReadTimeout(25000);
+ conn.setRequestMethod("POST");
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+
+ conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+ conn.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
+ conn.connect();
+
+ out = conn.getOutputStream();
+ out.write(data.getBytes(Charsets.UTF_8));
+ out.flush();
+
+ inputStream = conn.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(inputStream, Charsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ IOUtils.closeQuietly(out);
+ IOUtils.closeQuietly(reader);
+ IOUtils.closeQuietly(inputStream);
+ if (conn != null) {
+ conn.disconnect();
+ }
+ }
+ }
+
}
diff --git a/mallinkService/src/main/java/com/simple/utils/RandomUtils.java b/mallinkService/src/main/java/com/simple/utils/RandomUtils.java
new file mode 100644
index 000000000..5ef79a95e
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/utils/RandomUtils.java
@@ -0,0 +1,33 @@
+package com.simple.utils;
+
+public class RandomUtils {
+
+ private static String[] randomValues = new String[]{
+ "0","1","2","3","4","5","6","7","8","9",
+ "a","b","c","d","e","f","g","h","i","j",
+ "k","l","m","n","u","t","s","o","x","v",
+ "p","q","r","w","y","z"};
+
+ private static String[] randomNums = new String[]{
+ "0","1","2","3","4","5","6","7","8","9",
+ };
+
+ public static String getStr(int lenght) {
+ StringBuffer str = new StringBuffer();
+ for(int i = 0;i < lenght; i++) {
+ Double number=Math.random()*(randomValues.length-1);
+ str.append(randomValues[number.intValue()]);
+ }
+ return str.toString();
+ }
+
+ public static String getNum(int lenght) {
+ StringBuffer str = new StringBuffer();
+ for(int i = 0;i < lenght; i++) {
+ Double number=Math.random()*(randomNums.length-1);
+ str.append(randomNums[number.intValue()]);
+ }
+ return str.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/mallinkService/src/main/java/com/simple/utils/Utility.java b/mallinkService/src/main/java/com/simple/utils/Utility.java
new file mode 100644
index 000000000..347d70676
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/utils/Utility.java
@@ -0,0 +1,550 @@
+package com.simple.utils;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Stormeye
+ * @since 2018.08.09
+ */
+
+public final class Utility {
+ private final static Logger logger = LoggerFactory.getLogger(Utility.class);
+
+
+// @Autowired
+// private ReloadableResourceBundleMessageSource messageSource;
+
+ public static String generateUUID() {
+ return UUID.randomUUID().toString();
+ }
+
+ public static String generate32UUID() {
+ return UUID.randomUUID().toString().replaceAll("-", "");
+ }
+
+ public static boolean isEmpty(CharSequence str) {
+ if (str == null || str.length() == 0)
+ return true;
+ else
+ return false;
+ }
+
+ public static boolean isBlank(CharSequence str) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0) {
+ return true;
+ }
+ for (int i = 0; i < strLen; i++) {
+ if ((Character.isWhitespace(str.charAt(i)) == false)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * format time to "yyyy-MM-dd"
+ * @param time
+ * @return
+ */
+ public static String formatTime(int time){
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+ /**
+ * format timestamp to "yyyy-MM-dd HH:mm:ss"
+ * @param time
+ * @return
+ */
+ public static String formatTimestamp(int time){
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+
+ /**
+ * getSimpleRegionModel the day end time by given the time point
+ * e.g. given timePoint is "2015.5.13 13:45:32", the returned day end time is "2015.5.13 23:59:59"
+ * @param timePoint
+ * @return
+ */
+ public static int getDayEndTime(int timePoint){
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
+ long theTime = ((long)timePoint)*1000;
+ calendar.setTimeInMillis(theTime);
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+ int second = calendar.get(Calendar.SECOND);
+ calendar.clear();
+ calendar.set(year, month, day, 23, 59, 59);
+ int ret = (int)(calendar.getTimeInMillis()/1000);
+ return ret;
+ }
+
+ public static int getDayStartTime(int timePoint) {
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
+ long theTime = ((long)timePoint)*1000;
+ calendar.setTimeInMillis(theTime);
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ int minute = calendar.get(Calendar.MINUTE);
+ int second = calendar.get(Calendar.SECOND);
+ calendar.clear();
+ calendar.set(year, month, day, 0, 0, 0);
+ int ret = (int)(calendar.getTimeInMillis()/1000);
+ return ret;
+ }
+
+ public static int getLastHourEndTime(int timePoint) {
+ SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH");
+ String curHour = sf.format(System.currentTimeMillis());
+ int ret = timePoint;
+ try {
+ ret = (int)((sf.parse(curHour).getTime())/1000);
+ } catch(ParseException ex) {
+ ex.printStackTrace();
+ }
+ return ret - 1;
+ }
+
+ /**
+ * Encrypt plain text
+ * @param plainText
+ * @return encrypted string for cvn2
+ */
+ public static String encryptText(String plainText) {
+
+ return plainText;
+ }
+
+ /**
+ * Decrypt to plain text
+ * @param decryptedText
+ * @return encrypted string for cvn2
+ */
+ public static String decryptedText(String decryptedText) {
+
+ return decryptedText;
+ }
+
+ /**
+ * Mask the bankcard Number, e.g. 18911113927 to 189******3927
+ * @param idCardNo
+ * @return masked phone number
+ */
+ public static String maskIdCard(String idCardNo) {
+ if(isEmpty(idCardNo) || idCardNo.length() < 18) {
+ return idCardNo;
+ }
+ return idCardNo.substring(0,4) + "**" + idCardNo.substring(6, 12) + "***" + idCardNo.substring(15, 18);
+ }
+
+ /**
+ * Mask the bankcard Number, e.g. 18911113927 to 189******3927
+ * @param bankCardNo
+ * @return masked phone number
+ */
+ public static String maskBankCard(String bankCardNo) {
+ if(bankCardNo.length() <= 8) {
+ return bankCardNo;
+ }
+ return bankCardNo.substring(0,4) + "******" + bankCardNo.substring(bankCardNo.length() - 4, bankCardNo.length());
+ }
+
+ /**
+ * Mask the user name, e.g.
+ * @param userName
+ * @return masked phone number
+ */
+ public static String maskUserName(String userName) {
+ switch (userName.length()) {
+ case 0:
+ case 1:
+ return "*";
+ default:
+ return userName.replaceAll(".", "*").replaceFirst(".$",userName.substring(userName.length() - 1));
+ }
+ }
+
+ public static String maskPhoneNum(String phoneNum) {
+ if(phoneNum==null || phoneNum.length() < 4) {
+ return phoneNum;
+ }
+ return phoneNum.substring(0,3) + "****" + phoneNum.substring(phoneNum.length() - 4, phoneNum.length());
+ }
+
+ /**
+ * Convert current time into int type. used for create_time/update time
+ * @param
+ * @return timestamp
+ */
+ public static int getCurrentTimeStamp() {
+ if(debugCurrentTimeStamp == 0) {
+ return (int) (System.currentTimeMillis() / 1000);
+ }else {
+ return debugCurrentTimeStamp;
+ }
+ }
+
+ public static int convertDate2TimeStamp(Date date) {
+ return (int) (date.getTime() / 1000);
+ }
+
+
+ private static int debugCurrentTimeStamp = 0;
+
+ /**
+ * For test purpose, getCurrentTimeStamp will return the timestamp if non-zero.
+ * @param
+ * @return timestamp
+ */
+ public static void setDebugCurrentTimeStamp(int timeStamp) {
+ debugCurrentTimeStamp = timeStamp;
+ }
+
+
+ public static String generateInvitationCode(Set existingCode){
+ int invitationCode = (int)((Math.random()*9+1)*100000);
+ if(existingCode != null){
+ while(existingCode.contains(String.valueOf(invitationCode))){
+ invitationCode++;
+ if(invitationCode>=999999){
+ invitationCode = (int)((Math.random()*9+1)*100000);
+ }
+ }
+ }
+ return String.valueOf(invitationCode);
+ }
+
+ public static String generateOrderId(String gid) {
+ if (null == gid) {
+ return "";
+ }
+ return "SDLC" + gid.replaceAll("-", "");
+ }
+
+ public static String getDataFormatString(int currentSec) {
+ SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return sf.format(((long) currentSec) * 1000);
+ }
+
+ public static String getDataFormatString2(int currentSec) {
+ SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日");
+ return sf.format(((long) currentSec) * 1000);
+ }
+
+ public static String convertDecimal2PercentRate(BigDecimal rate) {
+ NumberFormat percent = NumberFormat.getPercentInstance();
+ percent.setMaximumFractionDigits(1);
+ return percent.format(rate.setScale(3, BigDecimal.ROUND_DOWN));
+ }
+
+ public static String convertLineFeedCharacter(String msg){
+ if(msg == null || msg.isEmpty()){
+ return "";
+ }
+ msg = msg.replace("\\\\n", "\\n");
+ return msg;
+ }
+
+ public static int getSimpleDayEndTime(int timePoint){
+ Calendar ca = new GregorianCalendar();
+ ca.setTime(new Date(((long) timePoint) * 1000));
+ ca.set(Calendar.HOUR_OF_DAY, 23);
+ ca.set(Calendar.MINUTE, 59);
+ ca.set(Calendar.SECOND, 59);
+ long ret = ca.getTime().getTime()/1000;
+ return (int) ret;
+ }
+
+ public static String urlEncodeUTF8(String s) {
+ try {
+ return URLEncoder.encode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new UnsupportedOperationException(e);
+ }
+ }
+
+ public static String urlDecodeUTF8(String s) {
+ try {
+ return URLDecoder.decode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new UnsupportedOperationException(e);
+ }
+ }
+
+ public static int dateStringToTimeStamp(String dateStr){
+ int timeStamp = 0;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ try {
+ Date date = sdf.parse(dateStr);
+ timeStamp= (int) (date.getTime()/1000);
+ } catch (ParseException e) {
+ logger.error("dateStringToTimeStamp exception = {}", e);
+ }
+ return timeStamp;
+ }
+ public static int dateStringToTimeStamp(String dateStr,String format){
+ int timeStamp = 0;
+ SimpleDateFormat sdf = new SimpleDateFormat(format);
+ try {
+ Date date = sdf.parse(dateStr);
+ timeStamp= (int) (date.getTime()/1000);
+ } catch (ParseException e) {
+ logger.error("dateStringToTimeStamp exception = {}", e);
+ }
+ return timeStamp;
+ }
+ public static Object convert(Object object, Class> type) {
+ if (object instanceof Number) {
+ Number number = (Number) object;
+ if (type.equals(byte.class) || type.equals(Byte.class)) {
+ return number.byteValue();
+ }
+ if (type.equals(short.class) || type.equals(Short.class)) {
+ return number.shortValue();
+ }
+ if (type.equals(int.class) || type.equals(Integer.class)) {
+ return number.intValue();
+ }
+ if (type.equals(long.class) || type.equals(Long.class)) {
+ return number.longValue();
+ }
+ if (type.equals(float.class) || type.equals(Float.class)) {
+ return number.floatValue();
+ }
+ if (type.equals(double.class) || type.equals(Double.class)) {
+ return number.doubleValue();
+ }
+ }
+ return object;
+ }
+
+ public static int getFirstDayByDate(final Date date) {
+ Calendar instance = Calendar.getInstance();
+ instance.setTime(date);
+ instance.set(instance.get(Calendar.YEAR), instance.get(Calendar.MONTH), 1, 0, 0, 0);
+ int ret = (int) (instance.getTimeInMillis()/1000);
+ return ret;
+ }
+
+ public static boolean decimalEqualsScale2(BigDecimal one , BigDecimal two) {
+ if (one == null || two == null) {
+ return false;
+ }
+
+ final BigDecimal o1 = one.setScale(2 , BigDecimal.ROUND_DOWN);
+ final BigDecimal o2 = two.setScale(2 , BigDecimal.ROUND_DOWN);
+ return o1.compareTo(o2) == 0;
+ }
+
+ public static int decimalCompareScale2(BigDecimal one , BigDecimal two) {
+ if (one == null || two == null) {
+ return -1;
+ }
+ final BigDecimal o1 = one.setScale(2 , BigDecimal.ROUND_DOWN);
+ final BigDecimal o2 = two.setScale(2 , BigDecimal.ROUND_DOWN);
+ return o1.compareTo(o2);
+ }
+
+ public static BigDecimal setScale2RoundDown(BigDecimal one) {
+ if (one == null) {
+ return null;
+ }
+ return one.setScale(2, BigDecimal.ROUND_DOWN);
+ }
+
+ public static boolean isNumeric(String str){
+ Pattern pattern = Pattern.compile("[0-9]*");
+ Matcher isNum = pattern.matcher(str);
+ if( !isNum.matches() ){
+ return false;
+ }
+ return true;
+ }
+
+ public static String dateFormat(Date date, String pattern) {
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ return sdf.format(date);
+ }
+
+ public static int getCurrentWeekStartTime(int dayTime) {
+ Calendar currentDate = Calendar.getInstance();
+ currentDate.setTime(new Date(dayTime * 1000L));
+ currentDate.setFirstDayOfWeek(Calendar.MONDAY);
+ currentDate.set(Calendar.HOUR_OF_DAY, 0);
+ currentDate.set(Calendar.MINUTE, 0);
+ currentDate.set(Calendar.SECOND, 0);
+ currentDate.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+ return (int)(currentDate.getTimeInMillis() / 1000L);
+ }
+
+ public static int getCurrentWeekEndTime(int dayTime) {
+ Calendar currentDate = Calendar.getInstance();
+ currentDate.setTime(new Date(dayTime * 1000L));
+ currentDate.setFirstDayOfWeek(Calendar.MONDAY);
+ currentDate.set(Calendar.HOUR_OF_DAY, 23);
+ currentDate.set(Calendar.MINUTE, 59);
+ currentDate.set(Calendar.SECOND, 59);
+ currentDate.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+ return (int)(currentDate.getTimeInMillis() / 1000L);
+ }
+
+ public static int getCurrentMonthStartTime(int dayTime) {
+ Calendar currentDate = Calendar.getInstance();
+ currentDate.setTime(new Date(dayTime * 1000L));
+ currentDate.set(Calendar.HOUR_OF_DAY, 0);
+ currentDate.set(Calendar.MINUTE, 0);
+ currentDate.set(Calendar.SECOND, 0);
+ currentDate.set(Calendar.DAY_OF_MONTH, currentDate
+ .getActualMinimum(Calendar.DAY_OF_MONTH));
+ return (int)(currentDate.getTimeInMillis() / 1000L);
+ }
+
+ public static int getCurrentMonthEndTime(int dayTime) {
+ Calendar currentDate = Calendar.getInstance();
+ currentDate.setTime(new Date(dayTime * 1000L));
+ currentDate.set(Calendar.HOUR_OF_DAY, 23);
+ currentDate.set(Calendar.MINUTE, 59);
+ currentDate.set(Calendar.SECOND, 59);
+ currentDate.set(Calendar.DAY_OF_MONTH, currentDate
+ .getActualMaximum(Calendar.DAY_OF_MONTH));
+ return (int)(currentDate.getTimeInMillis() / 1000L);
+ }
+
+ /**
+ * format time to "yyyy-MM-dd"
+ * @param time
+ * @return
+ */
+ public static String formatTimeYYMMDDHH(int time){
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHH");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+
+ public static String formatTimeMMDD(int time){
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("MMdd");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+
+ public static String formatTimeMMDotDD(int time) {
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("MM.dd");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+
+ public static String formatTimeYmdHm(int time) {
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+
+ public static int getDayByType(int time, int type) {
+ long t = time * 1000L;
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(new Date(t));
+ return calendar.get(type);
+ }
+
+ public static int addTime(int time , int type , int nums) {
+ long t = time * 1000L;
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(new Date(t));
+ calendar.add(type, nums);
+ return (int)(calendar.getTimeInMillis() / 1000L);
+ }
+
+ public static BigDecimal convertCoord2Decimal(Integer coordLat) {
+ return new BigDecimal(coordLat).divide(new BigDecimal(100000), 5, BigDecimal.ROUND_HALF_DOWN);
+ }
+
+ public static BigDecimal convertScale(Double amount) {
+ return amount != null ? new BigDecimal(amount).setScale(1,BigDecimal.ROUND_HALF_DOWN) : BigDecimal.ZERO;
+ }
+
+ public static String convertLevel(String level) {
+ if (level != null && level.matches("\\d+(.\\d+)?")) {
+ return new BigDecimal(level)
+ .multiply(new BigDecimal(2.0))
+ .setScale(1, BigDecimal.ROUND_HALF_UP).toString();
+ }
+ return level;
+ }
+
+ public static String getUTFString(String content) {
+ try {
+ return new String(content.getBytes("ISO-8859-1"), "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ /**
+ * 金额 分转换元(精确到2位小数)
+ * @param money (单位分)
+ * @return
+ */
+ public static BigDecimal getAmount(Integer money) {
+ return new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN);
+ }
+
+ public static String getDataFormatStringYYYYMMDDHHmmss(int currentSec) {
+ SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
+ return sf.format(((long) currentSec) * 1000);
+ }
+
+ public static String getOrderNo() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String dateStr = sdf.format(new Date());
+ return dateStr.substring(0,4)+dateStr.substring(5,7)+dateStr.substring(8,10)+dateStr.substring(11,13)+dateStr.substring(14,16)+dateStr.substring(17,19)+RandomUtils.getNum(5);
+ }
+
+ /**
+ * 金额 分转换元(精确到1位小数)
+ * @param money (单位角)
+ * @return
+ */
+ public static String getAmountStr(Integer money) {
+ return new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).toString();
+ }
+
+ /**
+ * format time to "yyyyMMdd"
+ * @param time
+ * @return
+ */
+ public static String formatTimeYmd(int time){
+ long t = time * 1000l;
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
+ String ret = formatter.format(new Date(t));
+ return ret;
+ }
+}
diff --git a/mallinkService/src/main/java/com/simple/utils/XmlUtil.java b/mallinkService/src/main/java/com/simple/utils/XmlUtil.java
new file mode 100644
index 000000000..d816f4f52
--- /dev/null
+++ b/mallinkService/src/main/java/com/simple/utils/XmlUtil.java
@@ -0,0 +1,388 @@
+package com.simple.utils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.*;
+import org.dom4j.tree.DefaultElement;
+
+import java.util.*;
+
+/**
+ * XML处理器
+ *
+ * @author XiongChun
+ * @since 2009-07-07
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public final class XmlUtil {
+ private static Log log = LogFactory.getLog(XmlUtil.class);
+
+ private XmlUtil() {
+ }
+
+ /**
+ * 解析XML并将其节点元素压入Dto返回(基于节点值形式的XML格式)
+ *
+ * @param pStrXml 待解析的XML字符串
+ * @return outDto 返回Dto
+ */
+ public static final Map parseXml2Map(String pStrXml) {
+ Map map = new HashMap();
+ String strTitle = "";
+ Document document = null;
+ try {
+ if (pStrXml.indexOf(" 0) {
+ map.put(e.getName(), Dom2Map(e));
+ } else
+ map.put(e.getName(), e.getText());
+ }
+ return map;
+ }
+
+ public static Map Dom2Map(Element e) {
+ Map map = new HashMap();
+ List list = e.elements();
+ if (list.size() > 0) {
+ for (int i = 0; i < list.size(); i++) {
+ Element iter = (Element) list.get(i);
+ List mapList = new ArrayList();
+
+ if (iter.elements().size() > 0) {
+ Map m = Dom2Map(iter);
+ if (map.get(iter.getName()) != null) {
+ Object obj = map.get(iter.getName());
+ if (!obj.getClass().getName().equals("java.util.ArrayList")) {
+ mapList = new ArrayList();
+ mapList.add(obj);
+ mapList.add(m);
+ }
+ if (obj.getClass().getName().equals("java.util.ArrayList")) {
+ mapList = (List) obj;
+ mapList.add(m);
+ }
+ map.put(iter.getName(), mapList);
+ } else
+ map.put(iter.getName(), m);
+ } else {
+ if (map.get(iter.getName()) != null) {
+ Object obj = map.get(iter.getName());
+ if (!obj.getClass().getName().equals("java.util.ArrayList")) {
+ mapList = new ArrayList();
+ mapList.add(obj);
+ mapList.add(iter.getText());
+ }
+ if (obj.getClass().getName().equals("java.util.ArrayList")) {
+ mapList = (List) obj;
+ mapList.add(iter.getText());
+ }
+ map.put(iter.getName(), mapList);
+ } else
+ map.put(iter.getName(), iter.getText());
+ }
+ }
+ } else
+ map.put(e.getName(), e.getText());
+ return map;
+ }
+
+ /**
+ * 解析XML并将其节点元素压入Dto返回(基于节点值形式的XML格式)
+ *
+ * @param pStrXml 待解析的XML字符串
+ * @param pXPath 节点路径(例如:"//paralist/row" 则表示根节点paralist下的row节点的xPath路径)
+ * @return outDto 返回Dto
+ */
+ public static final Map parseXml2Map(String pStrXml, String pXPath) {
+ Map map = new HashMap();
+ String strTitle = "";
+ Document document = null;
+ try {
+ if (pStrXml.indexOf("";
+ Document document = null;
+ try {
+ if (pStrXml.indexOf(" dom2Map(Document doc) {
+ Map maproot = new HashMap();
+ if (doc == null)
+ return maproot;
+ Element root = doc.getRootElement();
+
+ List list1 = root.elements();
+ for (Object obj : list1) {
+ Element element = (Element) obj;
+ Map map = new HashMap();
+ element2Map(element, map);
+ maproot.put(element.getName(), map);
+ }
+ return maproot;
+ }
+
+ /**
+ * Element to map
+ *
+ * @param e
+ * @return
+ */
+ public static void element2Map(Element e, Map map) {
+ List list = e.elements();
+ if (e.attributeCount() > 0) {
+ for (Object attri : e.attributes()) {
+ Attribute at = (Attribute) attri;
+ map.put(at.getName(), at.getValue());
+ }
+ }
+ if (list.size() < 1 && DataUtil.isEmpty(e.getText())) {
+ return;
+ } else if (list.size() < 1 && !DataUtil.isEmpty(e.getText())) {
+ map.put("text", e.getText());
+ }
+ for (Object aList : list) {
+ Element iter = (Element) aList;
+ Map cMap = new HashMap();
+ element2Map(iter, cMap);
+ map.put(iter.getName(), cMap);
+ }
+ }
+
+ /**
+ * 将mq查询结果包装成list--dto的形式,dto内容为item中的内容
+ *
+ * @param recv
+ * @return
+ */
+ public static Map MqResToDto(String recv) {
+ // System.out.println("####recv"+recv);
+ List res = new ArrayList();
+ Map map = new HashMap();
+ try {
+ Document doc = DocumentHelper.parseText(recv);
+ List list = doc.selectNodes("//item");
+ Iterator it = list.iterator();
+ while (it.hasNext()) {
+ Map elementdto = XmlUtil.Dom2Map(it.next());
+ res.add(elementdto);
+ }
+ map.put("resultList", res);// 放入结果集
+ /*
+ * 如果存在REC_MNT,说明是分页查询类,需要将总记录数返回
+ */
+ Node de = doc.selectSingleNode("//REC_MNT");
+ if (DataUtil.isNotEmpty(de)) {
+ map.put("countInteger", de.getText());
+ }
+ } catch (Exception e) {
+ log.error(XmlUtil.class, e);
+ }
+ return map;
+ }
+
+}
\ No newline at end of file