转载: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>