| @@ -10,4 +10,19 @@ | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <artifactId>mallinkService</artifactId> | |||
| <dependencies> | |||
| <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp --> | |||
| <dependency> | |||
| <groupId>com.squareup.okhttp3</groupId> | |||
| <artifactId>okhttp</artifactId> | |||
| <version>3.11.0</version> | |||
| </dependency> | |||
| <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j --> | |||
| <dependency> | |||
| <groupId>org.dom4j</groupId> | |||
| <artifactId>dom4j</artifactId> | |||
| <version>2.1.1</version> | |||
| </dependency> | |||
| </dependencies> | |||
| </project> | |||
| @@ -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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> params) { | |||
| return WxPay.doPost(MICROPAY_URL, params); | |||
| } | |||
| /** | |||
| * 企业付款 | |||
| * | |||
| * @param params | |||
| * 请求参数 | |||
| * @param certPath | |||
| * 证书文件目录 | |||
| * @param certPassword | |||
| * 证书密码 | |||
| * @return {String} | |||
| */ | |||
| public static String transfers(Map<String, String> 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<String, String> 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<String, String> packageParams = new HashMap<String, String>(); | |||
| 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<String, String> 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<String, String> params) { | |||
| return HttpUtil.payPost(url, WxPayment.toXml(params)); | |||
| } | |||
| public static String doPostSSL(String url, Map<String, String> params, String certPath, String certPass) { | |||
| return HttpUtil.payPostSSL(url, WxPayment.toXml(params), certPath, certPass); | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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<String, String> 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<String, String> queryParas = new HashMap<String, String>(); | |||
| 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<String, String> buildParasMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||
| String transaction_id, String out_trade_no, String paternerKey) { | |||
| Map<String, String> params = new HashMap<String, String>(); | |||
| 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<String, String> 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<String, String> params = new HashMap<String, String>(); | |||
| 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<String, String> buildShortUrlParasMap(String appid, String sub_appid, String mch_id, | |||
| String sub_mch_id, String long_url, String paternerKey) { | |||
| Map<String, String> params = new HashMap<String, String>(); | |||
| 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<String, String> params, boolean urlEncoder) { | |||
| // 先将参数以其参数名的字典序升序进行排序 | |||
| TreeMap<String, String> sortedParams = new TreeMap<String, String>(params); | |||
| // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起 | |||
| StringBuilder sb = new StringBuilder(); | |||
| boolean first = true; | |||
| for (Entry<String, String> 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<String, String> buildSignAfterParasMap(Map<String, String> 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<String, String> 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<String, String> 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<String, String> params) { | |||
| StringBuilder xml = new StringBuilder(); | |||
| xml.append("<xml>"); | |||
| for (Entry<String, String> 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("</xml>"); | |||
| return xml.toString(); | |||
| } | |||
| /** | |||
| * 针对支付的xml,没有嵌套节点的简单处理 | |||
| * | |||
| * @param xmlStr | |||
| * xml字符串 | |||
| * @return map集合 | |||
| */ | |||
| @SuppressWarnings("unchecked") | |||
| public static Map<String, String> 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; | |||
| } | |||
| } | |||
| @@ -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)<br> | |||
| * 实用于对如下对象做判断: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)<br> | |||
| * 实用于对如下对象做判断: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", "<br/> "); | |||
| 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> K ifNull(K k, K defaultValue) { | |||
| if (k == null) { | |||
| return defaultValue; | |||
| } | |||
| return k; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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<String> 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; | |||
| } | |||
| } | |||
| @@ -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处理器<br> | |||
| * | |||
| * @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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||
| Document document = null; | |||
| try { | |||
| if (pStrXml.indexOf("<?xml") < 0) | |||
| pStrXml = strTitle + pStrXml; | |||
| document = DocumentHelper.parseText(pStrXml); | |||
| } catch (DocumentException e) { | |||
| log.error("==开发人员请注意:==\n将XML格式的字符串转换为XML DOM对象时发生错误啦!" + "\n详细错误信息如下:", e); | |||
| } | |||
| // 获取根节点 | |||
| Element elNode = document.getRootElement(); | |||
| // 遍历节点属性值将其压入Dto | |||
| for (Iterator it = elNode.elementIterator(); it.hasNext();) { | |||
| Element leaf = (Element) it.next(); | |||
| map.put(leaf.getName().toLowerCase(), leaf.getData()); | |||
| } | |||
| return map; | |||
| } | |||
| /** | |||
| * 解析XML并将其节点元素压入Dto返回(基于节点值形式的XML格式) 应用于复杂对象 | |||
| * | |||
| * @param doc 待解析的XML字符串 | |||
| * @return outDto 返回Dto | |||
| */ | |||
| public static Map Dom2Map(Document doc) { | |||
| Map map = new HashMap(); | |||
| if (doc == null) | |||
| return map; | |||
| Element root = doc.getRootElement(); | |||
| for (Iterator iterator = root.elementIterator(); iterator.hasNext();) { | |||
| Element e = (Element) iterator.next(); | |||
| // System.out.println(e.getName()); | |||
| List list = e.elements(); | |||
| if (list.size() > 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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||
| Document document = null; | |||
| try { | |||
| if (pStrXml.indexOf("<?xml") < 0) | |||
| pStrXml = strTitle + pStrXml; | |||
| document = DocumentHelper.parseText(pStrXml); | |||
| } catch (DocumentException e) { | |||
| log.error("==开发人员请注意:==\n将XML格式的字符串转换为XML DOM对象时发生错误啦!" + "\n详细错误信息如下:", e); | |||
| } | |||
| // 获取根节点 | |||
| Element elNode = document.getRootElement(); | |||
| // 遍历节点属性值将其压入Dto | |||
| for (Iterator it = elNode.elementIterator(); it.hasNext();) { | |||
| Element leaf = (Element) it.next(); | |||
| map.put(leaf.getName().toLowerCase(), leaf.getData()); | |||
| } | |||
| return map; | |||
| } | |||
| /** | |||
| * 将Dto转换为符合XML标准规范格式的字符串(基于节点值形式) | |||
| * | |||
| * @param map 传入的Dto对象 | |||
| * @param pRootNodeName 根结点名 | |||
| * @return string 返回XML格式字符串 | |||
| */ | |||
| public static final String parseDto2Xml(Map map, String pRootNodeName) { | |||
| Document document = DocumentHelper.createDocument(); | |||
| // 增加一个根元素节点 | |||
| document.addElement(pRootNodeName); | |||
| Element root = document.getRootElement(); | |||
| Iterator keyIterator = map.keySet().iterator(); | |||
| while (keyIterator.hasNext()) { | |||
| String key = (String) keyIterator.next(); | |||
| String value = (String) map.get(key); | |||
| Element leaf = root.addElement(key); | |||
| leaf.setText(value); | |||
| } | |||
| // 将XML的头声明信息截去 | |||
| String outXml = document.asXML().substring(39); | |||
| return outXml; | |||
| } | |||
| /** | |||
| * 将Dto转换为符合XML标准规范格式的字符串(基于节点值形式) | |||
| * | |||
| * @param map 传入的Dto对象 | |||
| * @param pRootNodeName 根结点名 | |||
| * @return string 返回XML格式字符串 | |||
| */ | |||
| public static final String parseDto2XmlHasHead(Map map, String pRootNodeName) { | |||
| Document document = DocumentHelper.createDocument(); | |||
| // 增加一个根元素节点 | |||
| document.addElement(pRootNodeName); | |||
| Element root = document.getRootElement(); | |||
| Iterator keyIterator = map.keySet().iterator(); | |||
| while (keyIterator.hasNext()) { | |||
| String key = (String) keyIterator.next(); | |||
| String value = (String) map.get(key); | |||
| Element leaf = root.addElement(key); | |||
| leaf.setText(value); | |||
| } | |||
| // 将XML的头声明信息截去 | |||
| // String outXml = document.asXML().substring(39); | |||
| String outXml = document.asXML(); | |||
| return outXml; | |||
| } | |||
| /** | |||
| * 将Dto转换为符合XML标准规范格式的字符串(基于属性值形式) | |||
| * | |||
| * @param map 传入的Dto对象 | |||
| * @param pRootNodeName 根节点名 | |||
| * @param pFirstNodeName 一级节点名 | |||
| * @return string 返回XML格式字符串 | |||
| */ | |||
| public static final String parseMap2Xml(Map map, String pRootNodeName, String pFirstNodeName) { | |||
| Document document = DocumentHelper.createDocument(); | |||
| // 增加一个根元素节点 | |||
| document.addElement(pRootNodeName); | |||
| Element root = document.getRootElement(); | |||
| root.addElement(pFirstNodeName); | |||
| Element firstEl = (Element) document.selectSingleNode("/" + pRootNodeName + "/" + pFirstNodeName); | |||
| Iterator keyIterator = map.keySet().iterator(); | |||
| while (keyIterator.hasNext()) { | |||
| String key = (String) keyIterator.next(); | |||
| String value = (String) map.get(key); | |||
| firstEl.addAttribute(key, value); | |||
| } | |||
| // 将XML的头声明信息丢去 | |||
| String outXml = document.asXML().substring(39); | |||
| return outXml; | |||
| } | |||
| /** | |||
| * 将List数据类型转换为符合XML格式规范的字符串(基于节点属性值的方式) | |||
| * | |||
| * @param pList 传入的List数据(List对象可以是Dto、VO、Domain的属性集) | |||
| * @param pRootNodeName 根节点名称 | |||
| * @param pFirstNodeName 行节点名称 | |||
| * @return string 返回XML格式字符串 | |||
| */ | |||
| public static final String parseList2Xml(List pList, String pRootNodeName, String pFirstNodeName) { | |||
| Document document = DocumentHelper.createDocument(); | |||
| Element elRoot = document.addElement(pRootNodeName); | |||
| for (int i = 0; i < pList.size(); i++) { | |||
| Map map = (Map) pList.get(i); | |||
| Element elRow = elRoot.addElement(pFirstNodeName); | |||
| Iterator it = map.entrySet().iterator(); | |||
| while (it.hasNext()) { | |||
| Map.Entry entry = (Map.Entry) it.next(); | |||
| elRow.addAttribute((String) entry.getKey(), String.valueOf(entry.getValue())); | |||
| } | |||
| } | |||
| String outXml = document.asXML().substring(39); | |||
| return outXml; | |||
| } | |||
| /** | |||
| * 将List数据类型转换为符合XML格式规范的字符串(基于节点值的方式) | |||
| * | |||
| * @param pList 传入的List数据(List对象可以是Dto、VO、Domain的属性集) | |||
| * @param pRootNodeName 根节点名称 | |||
| * @param pFirstNodeName 行节点名称 | |||
| * @return string 返回XML格式字符串 | |||
| */ | |||
| public static final String parseList2XmlBasedNode(List pList, String pRootNodeName, String pFirstNodeName) { | |||
| Document document = DocumentHelper.createDocument(); | |||
| Element output = document.addElement(pRootNodeName); | |||
| for (int i = 0; i < pList.size(); i++) { | |||
| Map map = (Map) pList.get(i); | |||
| Element elRow = output.addElement(pFirstNodeName); | |||
| Iterator it = map.entrySet().iterator(); | |||
| while (it.hasNext()) { | |||
| Map.Entry entry = (Map.Entry) it.next(); | |||
| Element leaf = elRow.addElement((String) entry.getKey()); | |||
| leaf.setText(String.valueOf(entry.getValue())); | |||
| } | |||
| } | |||
| String outXml = document.asXML().substring(39); | |||
| return outXml; | |||
| } | |||
| /** | |||
| * 将XML规范的字符串转为List对象(XML基于节点属性值的方式) | |||
| * | |||
| * @param pStrXml 传入的符合XML格式规范的字符串 | |||
| * @return list 返回List对象 | |||
| */ | |||
| public static final List parseXml2List(String pStrXml) { | |||
| List lst = new ArrayList(); | |||
| String strTitle = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||
| Document document = null; | |||
| try { | |||
| if (pStrXml.indexOf("<?xml") < 0) | |||
| pStrXml = strTitle + pStrXml; | |||
| document = DocumentHelper.parseText(pStrXml); | |||
| } catch (DocumentException e) { | |||
| log.error("==开发人员请注意:==\n将XML格式的字符串转换为XML DOM对象时发生错误啦!" + "\n详细错误信息如下:", e); | |||
| } | |||
| // 获取到根节点 | |||
| Element elRoot = document.getRootElement(); | |||
| // 获取根节点的所有子节点元素 | |||
| Iterator elIt = elRoot.elementIterator(); | |||
| while (elIt.hasNext()) { | |||
| Element el = (Element) elIt.next(); | |||
| Iterator attrIt = el.attributeIterator(); | |||
| Map map = new HashMap(); | |||
| while (attrIt.hasNext()) { | |||
| Attribute attribute = (Attribute) attrIt.next(); | |||
| map.put(attribute.getName().toLowerCase(), attribute.getData()); | |||
| } | |||
| lst.add(map); | |||
| } | |||
| return lst; | |||
| } | |||
| /** | |||
| * Document to map | |||
| * | |||
| * @param doc | |||
| * @return | |||
| */ | |||
| public static Map<String, Object> dom2Map(Document doc) { | |||
| Map<String, Object> maproot = new HashMap<String, Object>(); | |||
| if (doc == null) | |||
| return maproot; | |||
| Element root = doc.getRootElement(); | |||
| List list1 = root.elements(); | |||
| for (Object obj : list1) { | |||
| Element element = (Element) obj; | |||
| Map<String, Object> map = new HashMap<String, Object>(); | |||
| element2Map(element, map); | |||
| maproot.put(element.getName(), map); | |||
| } | |||
| return maproot; | |||
| } | |||
| /** | |||
| * Element to map | |||
| * | |||
| * @param e | |||
| * @return | |||
| */ | |||
| public static void element2Map(Element e, Map<String, Object> map) { | |||
| List<Element> 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<String, Object> cMap = new HashMap<String, Object>(); | |||
| 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<DefaultElement> 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; | |||
| } | |||
| } | |||