把微信支付demo裏面的一些工具類整理了下,以備用!
目錄
HttpUtil 工具類
package util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
public class HttpUtil {
private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
private final static String DEFAULT_ENCODING = "UTF-8";
public static String postData(String urlStr, String data){
return postData(urlStr, data, null);
}
public static String postData(String urlStr, String data, String contentType){
BufferedReader reader = null;
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if(contentType != null)
conn.setRequestProperty("content-type", contentType);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if(data == null)
data = "";
writer.write(data);
writer.flush();
writer.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
System.err.println("Error connecting to " + urlStr + ": " + e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
return null;
}
}
MD5Util 工具類
package util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
public class MD5Util {
/**
* 編碼,將字節數組轉成可識別字符串
* @param b
* @return
*/
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
/**
* 將自己轉成可識別字符串
* @param b
* @return
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* 獲取指定內容的 MD5值
* @param origin 被轉換的內容
* @param charsetname 字符集
* @return
*/
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
public static String UrlEncode(String src) throws UnsupportedEncodingException {
return URLEncoder.encode(src, "UTF-8").replace("+", "%20");
}
}
PayUtil 工具類
package util;
import java.util.*;
public class PayUtil {
/**
* 統一下單,獲取二維碼字符串
* @param order_price 價格
* @param body 商品描述
* @param out_trade_no 訂單號
* @return
* @throws Exception
*/
public static String getPayURL( String body,String out_trade_no,String total_fee) throws Exception {
// 賬號信息
String appid = PayConfig.APP_ID; //appid
String mch_id = PayConfig.MCH_ID; //商業號
String key = PayConfig.API_KEY; //API密鑰
String nonce_str = RandomUtil.getRandomString(20); //隨即字符串,官方文檔要求長度在32位以內
String spbill_create_ip = PayConfig.CREATE_IP; //獲取發起電腦 ip
String notify_url = PayConfig.NOTIFY_URL; //回調接口
String trade_type = "NATIVE"; //支付類型
SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
packageParams.put("appid", appid);
packageParams.put("mch_id", mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("body", body);
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("total_fee", total_fee);
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("notify_url", notify_url);
packageParams.put("trade_type", trade_type);
String sign = SignUtil.createSign(packageParams,key);
packageParams.put("sign", sign);
String requestXML = XMLUtil.getRequestXml(packageParams);
System.out.println(requestXML);
System.out.println("--------------------");
String resXml = HttpUtil.postData(PayConfig.UFDOOER_URL, requestXML);
System.out.println(resXml);
Map map = XMLUtil.doXMLParse(resXml);
String urlCode = (String) map.get("code_url");
return urlCode;
}
}
RandomUtil 工具類
package util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class RandomUtil {
/**
* 主要用於生成隨機字符(nonce_str)
* @param length
* @return
*/
public static String getRandomString(int length){
Random random = new Random();
StringBuffer sb = new StringBuffer();
for(int i = 0; i < length; i++){
int number = random.nextInt(3);
long result = 0;
switch(number){
case 0:
result = Math.round(Math.random() * 25 + 65);
sb.append(String.valueOf((char)result));
break;
case 1:
result = Math.round(Math.random() * 25 + 97);
sb.append(String.valueOf((char)result));
break;
case 2:
sb.append(String.valueOf(new Random().nextInt(10)));
break;
}
}
return sb.toString();
}
/**
* 獲取當前時間
* @return
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
/**
* 用於生成訂單號
* 使用 (隨機字符串+當前時間) 拼接而成的字符串,作爲訂單號,
* 哪怕是同一時間生成的訂單,訂單號也不會相同。
* @return
*/
public static String createOrderId(int length){
String out_trade_no = getRandomString(length)+getCurrTime();
return out_trade_no;
}
}
SignUtil 工具類
package util;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
public class SignUtil {
/**
* 根據packageParams和API_KEY生成簽名
* @param packageParams
* @param API_KEY (API密鑰)
* @return
*/
public static String createSign(SortedMap<Object, Object> packageParams, String API_KEY){
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
return sign;
}
/**
* 是否簽名正確,規則是:按參數名稱a-z排序,遇到空值的參數不參加簽名。
* @return boolean
*/
public static boolean isTenpaySign( SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if(!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
//算出摘要
String mysign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toLowerCase();
String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();
return tenpaySign.equals(mysign);
}
}
XMLUtil 工具類
package util;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
//生成XML和解析 XML
public class XMLUtil {
/**
* @Description:將請求參數轉換爲xml格式的string
* @param parameters 請求參數
* @return
*/
public static String getRequestXml(SortedMap<Object, Object> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
}
/**
* 解析xml,返回第一級元素鍵值對。如果第一級元素有子節點,則此節點的值是子節點的xml數據。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map doXMLParse(String strxml) throws JDOMException, IOException {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
if(null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
}
m.put(k, v);
}
//關閉流
in.close();
return m;
}
/**
* 獲取子結點的xml
* @param children
* @return String
*/
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if(!children.isEmpty()) {
Iterator it = children.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if(!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
}
return sb.toString();
}
}
ZxingUtil 工具類
package util;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class ZxingUtil {
/**
* Zxing圖形碼生成工具
*
* @param contents : 內容
* @param format : 圖片格式,可選[png,jpg,bmp]
* @param width : 寬
* @param height : 高
* @param saveImgFilePath : 存儲圖片的完整位置,包含文件名
* @return
*/
public static Boolean encode(String contents, String format, int width, int height, String saveImgFilePath) {
Boolean bool = false;
BufferedImage image = createImage(contents,width,height);
if (image != null) {
bool = writeToFile(image, format, saveImgFilePath);
}
return bool;
}
public static void encode(String contents, int width, int height) {
createImage(contents,width, height);
}
public static BufferedImage createImage(String contents ,int width, int height) {
BufferedImage bufImg=null;
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
// 指定糾錯等級
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN, 10);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
// contents = new String(contents.getBytes("UTF-8"), "ISO-8859-1");
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageConfig config = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
bufImg = MatrixToImageWriter.toBufferedImage(bitMatrix, config);
} catch (Exception e) {
e.printStackTrace();
}
return bufImg;
}
/**
* 將BufferedImage對象寫入文件
*
* @param bufImg
* BufferedImage對象
* @param format
* 圖片格式,可選[png,jpg,bmp]
* @param saveImgFilePath
* 存儲圖片的完整位置,包含文件名
* @return
*/
@SuppressWarnings("finally")
public static Boolean writeToFile(BufferedImage bufImg, String format, String saveImgFilePath) {
Boolean bool = false;
try {
bool = ImageIO.write(bufImg, format, new File(saveImgFilePath));
} catch (Exception e) {
e.printStackTrace();
} finally {
return bool;
}
}
}