微信退款java
阿新 • • 發佈:2018-12-03
轉載:https://blog.csdn.net/maqingbin8888/article/details/83505771
微信退款介面
官方地址 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
具體的退款API呼叫介面為 https://api.mch.weixin.qq.com/secapi/pay/refund
//TODO 9.0 操作支付表,把當前的支付的狀態變成 退款狀態 state 1 ---> 2 //TODO 10 操作預約表,可以把當前的預約狀態取消 已支付--->退款 //TODO 11 操作使用者表,如果是充值退款的話,把使用者的現金 - 當前退款的money //TODO 12其他等等的操作,生成記錄單號之類的
關於證書的使用
將下載下來的證書放到專案中的路徑,然後在發起post請求時,使用這個證書加密傳送內容 比如你傳送的是ABC 加密後為密文
HttpClient的程式碼
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
核心的程式碼
import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * This example demonstrates how to create secure connections with a custom SSL * context. */ public class ClientCustomSSL { public static String SSLCERT_PATH="";//證書的路徑 public static String SSLCERT_PASSWORD;//證書的密籍 @SuppressWarnings("deprecation") public static String doRefund(String url,String data) throws Exception { //注意PKCS12證書 是從微信商戶平臺-》賬戶設定-》 API安全 中下載的 KeyStore keyStore = KeyStore.getInstance("PKCS12"); //指向你的證書的絕對路徑,帶著證書去訪問 FileInputStream instream = new FileInputStream(new File(SSLCERT_PATH));//P12檔案目錄 try { //下載證書時的密碼、預設密碼是你的MCHID mch_id keyStore.load(instream, SSLCERT_PASSWORD.toCharArray());//這裡寫密碼 } finally { instream.close(); } //下載證書時的密碼、預設密碼是你的MCHID mch_id SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, SSLCERT_PASSWORD.toCharArray())//這裡也是寫密碼的 .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); try { HttpPost httpost = new HttpPost(url); // 設定響應頭資訊 httpost.addHeader("Connection", "keep-alive"); httpost.addHeader("Accept", "*/*"); httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpost.addHeader("Host", "api.mch.weixin.qq.com"); httpost.addHeader("X-Requested-With", "XMLHttpRequest"); httpost.addHeader("Cache-Control", "max-age=0"); httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); httpost.setEntity(new StringEntity(data, "UTF-8")); CloseableHttpResponse response = httpclient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); EntityUtils.consume(entity); return jsonStr; } finally { response.close(); } } finally { httpclient.close(); } } }
這後面的可以不用看了。
我的專案程式碼:
package wxRefund2; import java.io.*; import java.security.KeyStore; import java.util.HashMap; import java.util.Map; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; //import org.apache.http.conn.ssl.SSLContexts;//過期 import org.apache.http.ssl.SSLContexts;//最新 import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * This example demonstrates how to create secure connections with a custom SSL * context. */ public class ClientCustomSSL { public static String SSLCERT_PATH="D:\\12312321312.p12";//證書的路徑 public static String SSLCERT_PASSWORD ="123456789sjdk";//證書的密籍(密碼,商戶id) @SuppressWarnings("deprecation") public static String doRefund(String url,String data) throws Exception { //注意PKCS12證書 是從微信商戶平臺-》賬戶設定-》 API安全 中下載的 KeyStore keyStore = KeyStore.getInstance("PKCS12"); //指向你的證書的絕對路徑,帶著證書去訪問 FileInputStream instream = new FileInputStream(new File(SSLCERT_PATH));//P12檔案目錄 try { //下載證書時的密碼、預設密碼是你的MCHID mch_id keyStore.load(instream, SSLCERT_PASSWORD.toCharArray());//這裡寫密碼 } finally { instream.close(); } //下載證書時的密碼、預設密碼是你的MCHID mch_id SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, SSLCERT_PASSWORD.toCharArray())//這裡也是寫密碼的 .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); try { HttpPost httpost = new HttpPost(url); // 設定響應頭資訊 httpost.addHeader("Connection", "keep-alive"); httpost.addHeader("Accept", "*/*"); httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpost.addHeader("Host", "api.mch.weixin.qq.com"); httpost.addHeader("X-Requested-With", "XMLHttpRequest"); httpost.addHeader("Cache-Control", "max-age=0"); httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); httpost.setEntity(new StringEntity(data, "UTF-8")); CloseableHttpResponse response = httpclient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); EntityUtils.consume(entity); System.out.println(jsonStr); return jsonStr; } finally { response.close(); } } finally { httpclient.close(); } } public static void main(String [] args){ try { String url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; String xml = "";//請求引數xml字串 doRefund(url, xml); }catch (Exception e){ e.printStackTrace(); System.out.println(e.getMessage()); } } }
生成xml字串引數程式碼:
import sdk.PayLog;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
public static String getXml(HttpServletRequest request, HttpServletResponse response, String appId,
String secret, String shh, String key, String orderId, String total_fee, String refund_fee) {
String refundId = UUIDTool.getUUID();
String nonce_str = MD5Util.MD5Encode((String.valueOf(new Random().nextInt(10000))), "");//MD5Util.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
/*----- 1.生成預支付訂單需要的的package資料-----*/
SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put("appid", appId);
packageParams.put("mch_id", shh);//商戶號
packageParams.put("nonce_str", nonce_str);//隨機字串
packageParams.put("op_user_id", shh);//操作員帳號
packageParams.put("out_trade_no", orderId);//商戶訂單號
packageParams.put("out_refund_no", refundId);//商戶退單號
packageParams.put("total_fee", total_fee);//訂單總金額
packageParams.put("refund_fee", refund_fee);//退款總金額
/*----2.根據package生成簽名sign---- */
RequestHandler reqHandler = new RequestHandler(request, response);
reqHandler.init(appId, secret, key);
String sign = reqHandler.createSign(packageParams);
/*----3.拼裝需要提交到微信的資料xml---- */
String xml = "<xml>"
+ "<appid>" + appId + "</appid>"
+ "<mch_id>" + shh + "</mch_id>"
+ "<nonce_str>" + nonce_str + "</nonce_str>"
+ "<op_user_id>" + shh + "</op_user_id>"
+ "<out_trade_no>" + orderId + "</out_trade_no>"
+ "<out_refund_no>" + refundId + "</out_refund_no>"
+ "<refund_fee>" + refund_fee + "</refund_fee>"
+ "<total_fee>" + total_fee + "</total_fee>"
+ "<sign>" + sign + "</sign>"
+ "</xml>";
System.out.println(xml);
return xml;
}
RequestHandler
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/*
'微信支付伺服器簽名支付請求請求類
'============================================================================
'api說明:
'init(app_id, app_secret, partner_key, app_key);
'初始化函式,預設給一些引數賦值,如cmdno,date等。
'setKey(key_)'設定商戶金鑰
'getLasterrCode(),獲取最後錯誤號
'GetToken();獲取Token
'getTokenReal();Token過期後實時獲取Token
'createMd5Sign(signParams);生成Md5簽名
'genPackage(packageParams);獲取package包
'createSHA1Sign(signParams);建立簽名SHA1
'sendPrepay(packageParams);提交預支付
'getDebugInfo(),獲取debug資訊
'============================================================================
'*/
public class RequestHandler {
/** Token獲取閘道器地址地址 */
private String tokenUrl;
/** 預支付閘道器url地址 */
private String gateUrl;
/** 查詢支付通知閘道器URL */
private String notifyUrl;
/** 商戶引數 */
private String appid;
private String appkey;
private String partnerkey;
private String appsecret;
private String key;
/** 請求的引數 */
private SortedMap parameters;
/** Token */
private String Token;
private String charset;
/** debug資訊 */
private String debugInfo;
private String last_errcode;
private HttpServletRequest request;
private HttpServletResponse response;
/**
* 初始建構函式。
*
* @return
*/
public RequestHandler(HttpServletRequest request,
HttpServletResponse response) {
this.last_errcode = "0";
this.request = request;
this.response = response;
//this.charset = "GBK";
this.charset = "UTF-8";
this.parameters = new TreeMap();
// 驗證notify支付訂單閘道器
notifyUrl = "https://gw.tenpay.com/gateway/simpleverifynotifyid.xml";
}
public RequestHandler() {
this.last_errcode = "0";
//this.charset = "GBK";
this.charset = "UTF-8";
this.parameters = new TreeMap();
// 驗證notify支付訂單閘道器
notifyUrl = "https://gw.tenpay.com/gateway/simpleverifynotifyid.xml";
}
/**
* 初始化函式。
*/
public void init(String app_id, String app_secret, String partner_key) {
this.last_errcode = "0";
this.Token = "token_";
this.debugInfo = "";
this.appid = app_id;
this.partnerkey = partner_key;
this.appsecret = app_secret;
this.key = partner_key;
}
public void init() {
}
/**
* 獲取最後錯誤號
*/
public String getLasterrCode() {
return last_errcode;
}
/**
*獲取入口地址,不包含引數值
*/
public String getGateUrl() {
return gateUrl;
}
/**
* 獲取引數值
*
* @param parameter
* 引數名稱
* @return String
*/
public String getParameter(String parameter) {
String s = (String) this.parameters.get(parameter);
return (null == s) ? "" : s;
}
//設定金鑰
public void setKey(String key) {
this.partnerkey = key;
}
//設定微信金鑰
public void setAppKey(String key){
this.appkey = key;
}
// 特殊字元處理
public String UrlEncode(String src) throws UnsupportedEncodingException {
return URLEncoder.encode(src, this.charset).replace("+", "%20");
}
// 獲取package的簽名包
public String genPackage(SortedMap<String, String> packageParams)
throws UnsupportedEncodingException {
String sign = createSign(packageParams);
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();
sb.append(k + "=" + UrlEncode(v) + "&");
}
// 去掉最後一個&
String packageValue = sb.append("sign=" + sign).toString();
// System.out.println("UrlEncode後 packageValue=" + packageValue);
return packageValue;
}
/**
* 建立md5摘要,規則是:按引數名稱a-z排序,遇到空值的引數不參加簽名。
*/
public String createSign(SortedMap<String, String> packageParams) {
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=" + this.getKey());
System.out.println("md5 sb:" + sb+"key="+this.getKey());
String sign = MD5Util.MD5Encode(sb.toString(), this.charset)
.toUpperCase();
System.out.println("packge簽名:" + sign);
return sign;
}
/**
* 建立package簽名
*/
public boolean createMd5Sign(String signParams) {
StringBuffer sb = new StringBuffer();
Set es = this.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 (!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
// 算出摘要
String enc = TenpayUtil.getCharacterEncoding(this.request,
this.response);
String sign = MD5Util.MD5Encode(sb.toString(), enc).toLowerCase();
String tenpaySign = this.getParameter("sign").toLowerCase();
// debug資訊
this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:"
+ tenpaySign);
return tenpaySign.equals(sign);
}
//輸出XML
public String parseXML() {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = this.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(null != v && !"".equals(v) && !"appkey".equals(k)) {
sb.append("<" + k +">" + getParameter(k) + "</" + k + ">\n");
}
}
sb.append("</xml>");
return sb.toString();
}
/**
* 設定debug資訊
*/
protected void setDebugInfo(String debugInfo) {
this.debugInfo = debugInfo;
}
public void setPartnerkey(String partnerkey) {
this.partnerkey = partnerkey;
}
public String getDebugInfo() {
return debugInfo;
}
public String getKey() {
return partnerkey;
}
}
PayLog:
/**
* Created by Administrator on 2018/11/28.
*/
public class PayLog {
private String payCode;
private String payPrice;
private String refundCode;
public String getPayCode() {
return payCode;
}
public void setPayCode(String payCode) {
this.payCode = payCode;
}
public String getPayPrice() {
return payPrice;
}
public void setPayPrice(String payPrice) {
this.payPrice = payPrice;
}
public String getRefundCode() {
return refundCode;
}
public void setRefundCode(String refundCode) {
this.refundCode = refundCode;
}
/**
* 將元為單位的轉換為分 替換小數點,支援以逗號區分的金額
*
* @param amount
* @return
*/
public static String changeY2F(String amount) {
String currency = amount.replaceAll("\\$|\\¥|\\,", ""); //處理包含,¥或者$的金額
int index = currency.indexOf(".");
int length = currency.length();
Long amLong = 0l;
if (index == -1) {
amLong = Long.valueOf(currency + "00");
} else if (length - index >= 3) {
amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
} else if (length - index == 2) {
amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
} else {
amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
}
return amLong.toString();
}
}
MD5Util:
import java.security.MessageDigest;
public class MD5Util {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
UUIDTool:
import java.util.UUID;
/**
* Created by Administrator on 2018/12/3.
*/
public class UUIDTool {
public UUIDTool() {
}
/**
* 自動生成32位的UUid,對應資料庫的主鍵id進行插入用。
* @return
*/
public static String getUUID() {
/*UUID uuid = UUID.randomUUID();
String str = uuid.toString();
// 去掉"-"符號
String temp = str.substring(0, 8) + str.substring(9, 13)
+ str.substring(14, 18) + str.substring(19, 23)
+ str.substring(24);
return temp;*/
return UUID.randomUUID().toString().replace("-", "");
}
}
將所有價格(元)轉分:
public static String changeY2F(String amount) {
String currency = amount.replaceAll("\\$|\\¥|\\,", ""); //處理包含,¥或者$的金額
int index = currency.indexOf(".");
int length = currency.length();
Long amLong = 0l;
if (index == -1) {
amLong = Long.valueOf(currency + "00");
} else if (length - index >= 3) {
amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
} else if (length - index == 2) {
amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
} else {
amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
}
return amLong.toString();
}
TenpayUtil:這個類沒有用到
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TenpayUtil {
private static Object Server;
private static String QRfromGoogle;
/**
* 把物件轉換成字串
* @param obj
* @return String 轉換成字串,若物件為null,則返回空字串.
*/
public static String toString(Object obj) {
if(obj == null)
return "";
return obj.toString();
}
/**
* 把物件轉換為int數值.
* @param obj
* 包含數字的物件.
* @return int 轉換後的數值,對不能轉換的物件返回0。
*/
public static int toInt(Object obj) {
int a = 0;
try {
if (obj != null)
a = Integer.parseInt(obj.toString());
} catch (Exception e) {
}
return a;
}
/**
* 獲取當前時間 yyyyMMddHHmmss
* @return String
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
/**
* 獲取當前日期 yyyyMMdd
* @param date
* @return String
*/
public static String formatDate(Date date) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
String strDate = formatter.format(date);
return strDate;
}
/**
* 取出一個指定長度大小的隨機正整數.
* @param length
* int 設定所取出隨機數的長度。length小於11
* @return int 返回生成的隨機數。
*/
public static int buildRandom(int length) {
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < length; i++) {
num = num * 10;
}
return (int) ((random * num));
}
/**
* 獲取編碼字符集
* @param request
* @param response
* @return String
*/
public static String getCharacterEncoding(HttpServletRequest request,
HttpServletResponse response) {
if(null == request || null == response) {
return "utf-8";
}
String enc = request.getCharacterEncoding();
if(null == enc || "".equals(enc)) {
enc = response.getCharacterEncoding();
}
if(null == enc || "".equals(enc)) {
enc = "utf-8";
}
return enc;
}
public static String URLencode(String content){
String URLencode;
URLencode= replace(Server.equals(content), "+", "%20");
return URLencode;
}
private static String replace(boolean equals, String string, String string2) {
return null;
}
/**
* 獲取unix時間,從1970-01-01 00:00:00開始的秒數
* @param date
* @return long
*/
public static long getUnixTime(Date date) {
if( null == date ) {
return 0;
}
return date.getTime()/1000;
}
public static String QRfromGoogle(String chl)
{
int widhtHeight = 300;
String EC_level = "L";
int margin = 0;
String QRfromGoogle;
chl = URLencode(chl);
QRfromGoogle = "http://chart.apis.google.com/chart?chs=" + widhtHeight + "x" + widhtHeight + "&cht=qr&chld=" + EC_level + "|" + margin + "&chl=" + chl;
return QRfromGoogle;
}
/**
* 時間轉換成字串
* @param date 時間
* @param formatType 格式化型別
* @return String
*/
public static String date2String(Date date, String formatType) {
SimpleDateFormat sdf = new SimpleDateFormat(formatType);
return sdf.format(date);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>weixintuikuan</groupId>
<artifactId>weixintuikuan</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.github.liyiorg</groupId>
<artifactId>weixin-popular</artifactId>
<version>2.8.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!---->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.4</version>
</dependency>
<!-- jsoup包依賴 -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.1</version>
</dependency>
<!--json-->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!--spirng-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!--endSpring-->
<!--日誌 start-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--日誌end-->
<!--dom-->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<!--EndDom-->
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<!--EndHttpclient-->
</dependencies>
</project>