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(""); + } + 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