国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
支付寶登錄接口解析

昨天看了支付寶的登錄接口代碼,覺得有些東西還是對(duì)以后的開發(fā)有幫助的。下面就記錄自己的感想。

首先是AlipayCore.java這個(gè)類,該類是請(qǐng)求、通知返回兩個(gè)文件所調(diào)用的公用函數(shù)核心處理文件,不需要修改。方法主要是對(duì)簽名和請(qǐng)求參數(shù)進(jìn)行拼接:

/**  
* 生成簽名結(jié)果
* @param sArray 要簽名的數(shù)組
* @return 簽名結(jié)果字符串
*/
public static String buildMysign(Map<String, String> sArray) {
String prestr = createLinkString(sArray); //把數(shù)組所有元素,按照“參數(shù)=參數(shù)值”的模式用“&”字符拼接成字符串
prestrprestr = prestr + AlipayConfig.key; //把拼接后的字符串再與安全校驗(yàn)碼直接連接起來(lái)
String mysign = AlipayMd5Encrypt.md5(prestr);
return mysign;
}

/**
* 除去數(shù)組中的空值和簽名參數(shù)
* @param sArray 簽名參數(shù)組
* @return 去掉空值與簽名參數(shù)后的新簽名參數(shù)組
*/
public static Map<String, String> paraFilter(Map<String, String> sArray) {

Map<String, String> result = new HashMap<String, String>();

if (sArray == null || sArray.size() <= 0) {
return result;
}

for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
|| key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}

return result;
}

/**
* 把數(shù)組所有元素排序,并按照“參數(shù)=參數(shù)值”的模式用“&”字符拼接成字符串
* @param params 需要排序并參與字符拼接的參數(shù)組
* @return 拼接后字符串
*/
public static String createLinkString(Map<String, String> params) {

List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);

String prestr = "";

for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);

if (i == keys.size() - 1) {//拼接時(shí),不包括最后一個(gè)&字符
prestrprestr = prestr + key + "=" + value;
} else {
prestrprestr = prestr + key + "=" + value + "&";
}
}

return prestr;
}
AlipayConfig.java這個(gè)類是一個(gè)基礎(chǔ)配置類,主要用來(lái)設(shè)置賬戶有關(guān)信息和返回路徑:
//↓↓↓↓↓↓↓↓↓↓請(qǐng)?jiān)谶@里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓  
// 合作身份者ID,以2088開頭由16位純數(shù)字組成的字符串
public static String partner = "";

// 交易安全檢驗(yàn)碼,由數(shù)字和字母組成的32位字符串
public static String key = "";

// 當(dāng)前頁(yè)面跳轉(zhuǎn)后的頁(yè)面 要用 http://格式的完整路徑,不允許加?id=123這類自定義參數(shù)
// 域名不能寫成http://localhost/alipay.auth.authorize_jsp_utf8/return_url.jsp ,否則會(huì)導(dǎo)致return_url執(zhí)行無(wú)效
public static String return_url = "http://127.0.0.1:8080/alipay.auth.authorize_jsp_utf8/return_url.jsp";

//↑↑↑↑↑↑↑↑↑↑請(qǐng)?jiān)谶@里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑


// 調(diào)試用,創(chuàng)建TXT日志路徑
public static String log_path = "D:\\alipay_log_" + System.currentTimeMillis()+".txt";

// 字符編碼格式 目前支持 gbk 或 utf-8
public static String input_charset = "UTF-8";

// 簽名方式 不需修改
public static String sign_type = "MD5";

//訪問(wèn)模式,根據(jù)自己的服務(wù)器是否支持ssl訪問(wèn),若支持請(qǐng)選擇https;若不支持請(qǐng)選擇http
public static String transport = "http";
AlipayMd5Encrypt.java這個(gè)類是對(duì)簽名進(jìn)行加密的工具類,不需要修改即可用:
/**  
* 對(duì)字符串進(jìn)行MD5簽名
*
* @param text
* 明文
*
* @return 密文
*/
public static String md5(String text) {

return DigestUtils.md5Hex(getContentBytes(text, AlipayConfig.input_charset));

}

/**
* @param content
* @param charset
* @return
* @throws SignatureException
* @throws UnsupportedEncodingException
*/
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}

try {
return content.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("MD5簽名過(guò)程中出現(xiàn)錯(cuò)誤,指定的編碼集不對(duì),您目前指定的編碼集是:" + charset);
}
}
接下來(lái)是AlipayNotify.java這個(gè)類,這個(gè)類主要是處理支付寶各接口通知返回:
/**  
* HTTPS形式消息驗(yàn)證地址
*/
private static final String HTTPS_VERIFY_URL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify&";

/**
* HTTP形式消息驗(yàn)證地址
*/
private static final String HTTP_VERIFY_URL = "http://notify.alipay.com/trade/notify_query.do?";

/**
* 驗(yàn)證消息是否是支付寶發(fā)出的合法消息
* @param params 通知返回來(lái)的參數(shù)數(shù)組
* @return 驗(yàn)證結(jié)果
*/
public static boolean verify(Map<String, String> params) {
String mysign = getMysign(params);
String responseTxt = "true";
if(params.get("notify_id") != null) {responseTxt = verifyResponse(params.get("notify_id"));}
String sign = "";
if(params.get("sign") != null) {sign = params.get("sign");}

//寫日志記錄(若要調(diào)試,請(qǐng)取消下面兩行注釋)
//String sWord = "responseTxt=" + responseTxt + "\n notify_url_log:sign=" + sign + "&mysign="
// + mysign + "\n notify回來(lái)的參數(shù):" + AlipayCore.createLinkString(params);
//AlipayCore.logResult(sWord);


//驗(yàn)證
//responsetTxt的結(jié)果不是true,與服務(wù)器設(shè)置問(wèn)題、合作身份者ID、notify_id一分鐘失效有關(guān)
//mysign與sign不等,與安全校驗(yàn)碼、請(qǐng)求時(shí)的參數(shù)格式(如:帶自定義參數(shù)等)、編碼格式有關(guān)
if (mysign.equals(sign) && responseTxt.equals("true")) {
return true;
} else {
return false;
}
}

/**
* 根據(jù)反饋回來(lái)的信息,生成簽名結(jié)果
* @param Params 通知返回來(lái)的參數(shù)數(shù)組
* @return 生成的簽名結(jié)果
*/
private static String getMysign(Map<String, String> Params) {
Map<String, String> sParaNew = AlipayCore.paraFilter(Params);//過(guò)濾空值、sign與sign_type參數(shù)
String mysign = AlipayCore.buildMysign(sParaNew);//獲得簽名結(jié)果
return mysign;
}

/**
* 獲取遠(yuǎn)程服務(wù)器ATN結(jié)果,驗(yàn)證返回URL
* @param notify_id 通知校驗(yàn)ID
* @return 服務(wù)器ATN結(jié)果
* 驗(yàn)證結(jié)果集:
* invalid命令參數(shù)不對(duì) 出現(xiàn)這個(gè)錯(cuò)誤,請(qǐng)檢測(cè)返回處理中partner和key是否為空
* true 返回正確信息
* false 請(qǐng)檢查防火墻或者是服務(wù)器阻止端口問(wèn)題以及驗(yàn)證時(shí)間是否超過(guò)一分鐘
*/
private static String verifyResponse(String notify_id) {
//獲取遠(yuǎn)程服務(wù)器ATN結(jié)果,驗(yàn)證是否是支付寶服務(wù)器發(fā)來(lái)的請(qǐng)求
String transport = AlipayConfig.transport;
String partner = AlipayConfig.partner;
String veryfy_url = "";
if (transport.equalsIgnoreCase("https")) {
veryfy_url = HTTPS_VERIFY_URL;
} else {
veryfy_url = HTTP_VERIFY_URL;
}
veryfy_urlveryfy_url = veryfy_url + "partner=" + partner + "?ify_id=" + notify_id;

return checkUrl(veryfy_url);
}

/**
* 獲取遠(yuǎn)程服務(wù)器ATN結(jié)果
* @param urlvalue 指定URL路徑地址
* @return 服務(wù)器ATN結(jié)果
* 驗(yàn)證結(jié)果集:
* invalid命令參數(shù)不對(duì) 出現(xiàn)這個(gè)錯(cuò)誤,請(qǐng)檢測(cè)返回處理中partner和key是否為空
* true 返回正確信息
* false 請(qǐng)檢查防火墻或者是服務(wù)器阻止端口問(wèn)題以及驗(yàn)證時(shí)間是否超過(guò)一分鐘
*/
private static String checkUrl(String urlvalue) {
String inputLine = "";

try {
URL url = new URL(urlvalue);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection
.getInputStream()));
ininputLine = in.readLine().toString();
} catch (Exception e) {
e.printStackTrace();
inputLine = "";
}

return inputLine;
}
下面我們就需要進(jìn)行alipay的訪問(wèn)請(qǐng)求了,在請(qǐng)求過(guò)程中我們要有請(qǐng)求參數(shù)數(shù)組,提交的表單,有了這些條件之后我們就可以進(jìn)行模擬HTTP請(qǐng)求獲得返回的數(shù)據(jù)了。生成請(qǐng)求參數(shù)數(shù)組的代碼如下:
/**  
* 生成要請(qǐng)求給支付寶的參數(shù)數(shù)組
* @param sParaTemp 請(qǐng)求前的參數(shù)數(shù)組
* @return 要請(qǐng)求的參數(shù)數(shù)組
*/
private static Map<String, String> buildRequestPara(Map<String, String> sParaTemp) {
//除去數(shù)組中的空值和簽名參數(shù)
Map<String, String> sPara = AlipayCore.paraFilter(sParaTemp);
//生成簽名結(jié)果
String mysign = AlipayCore.buildMysign(sPara);

//簽名結(jié)果與簽名方式加入請(qǐng)求提交參數(shù)組中
sPara.put("sign", mysign);
sPara.put("sign_type", AlipayConfig.sign_type);

return sPara;
}
構(gòu)造提交表單代碼:
/**  
* 構(gòu)造提交表單HTML數(shù)據(jù)
* @param sParaTemp 請(qǐng)求參數(shù)數(shù)組
* @param gateway 網(wǎng)關(guān)地址
* @param strMethod 提交方式。兩個(gè)值可選:post、get
* @param strButtonName 確認(rèn)按鈕顯示文字
* @return 提交表單HTML文本
*/
public static String buildForm(Map<String, String> sParaTemp, String gateway, String strMethod,
String strButtonName) {
//待請(qǐng)求參數(shù)數(shù)組
Map<String, String> sPara = buildRequestPara(sParaTemp);
List<String> keys = new ArrayList<String>(sPara.keySet());

StringBuffer sbHtml = new StringBuffer();

sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\"" + gateway
+ "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
+ "\">");

for (int i = 0; i < keys.size(); i++) {
String name = (String) keys.get(i);
String value = (String) sPara.get(name);

sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
}

//submit按鈕控件請(qǐng)不要含有name屬性
sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");

return sbHtml.toString();
}
構(gòu)造模擬遠(yuǎn)程HTTP的POST請(qǐng)求,獲取支付寶的返回XML處理結(jié)果:
public static String sendPostInfo(Map<String, String> sParaTemp, String gateway)  
throws Exception {
//待請(qǐng)求參數(shù)數(shù)組
Map<String, String> sPara = buildRequestPara(sParaTemp);

HttpProtocolHandler httpProtocolHandler = HttpProtocolHandler.getInstance();

HttpRequest request = new HttpRequest(HttpResultType.BYTES);
//設(shè)置編碼集
request.setCharset(AlipayConfig.input_charset);

request.setParameters(generatNameValuePair(sPara));
request.setUrl(gateway+"_input_charset="+AlipayConfig.input_charset);

HttpResponse response = httpProtocolHandler.execute(request);
if (response == null) {
return null;
}

String strResult = response.getStringResult();

return strResult;
}
generatNameValuePair方法:
/**  
* MAP類型數(shù)組轉(zhuǎn)換成NameValuePair類型
* @param properties MAP類型數(shù)組
* @return NameValuePair類型數(shù)組
*/
private static NameValuePair[] generatNameValuePair(Map<String, String> properties) {
NameValuePair[] nameValuePair = new NameValuePair[properties.size()];
int i = 0;
for (Map.Entry<String, String> entry : properties.entrySet()) {
nameValuePair[i++] = new NameValuePair(entry.getKey(), entry.getValue());
}

return nameValuePair;
}
接下來(lái)要看看HttpProtocolHandler.java這個(gè)類了,這個(gè)類是模擬HTTP請(qǐng)求的核心類,最主要的是execute這個(gè)執(zhí)行http請(qǐng)求的方法:
public HttpResponse execute(HttpRequest request) {  
HttpClient httpclient = new HttpClient(connectionManager);

// 設(shè)置連接超時(shí)
int connectionTimeout = defaultConnectionTimeout;
if (request.getConnectionTimeout() > 0) {
connectionTimeout = request.getConnectionTimeout();
}
httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);

// 設(shè)置回應(yīng)超時(shí)
int soTimeout = defaultSoTimeout;
if (request.getTimeout() > 0) {
soTimeout = request.getTimeout();
}
httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);

// 設(shè)置等待ConnectionManager釋放connection的時(shí)間
httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);

String charset = request.getCharset();
charsetcharset = charset == null ? DEFAULT_CHARSET : charset;
HttpMethod method = null;

if (request.getMethod().equals(HttpRequest.METHOD_GET)) {
method = new GetMethod(request.getUrl());
method.getParams().setCredentialCharset(charset);

// parseNotifyConfig會(huì)保證使用GET方法時(shí),request一定使用QueryString
method.setQueryString(request.getQueryString());
} else {
method = new PostMethod(request.getUrl());
((PostMethod) method).addParameters(request.getParameters());
method.addRequestHeader("Content-Type",
"application/x-www-form-urlencoded; text/html; charset=" + charset);

}

// 設(shè)置Http Header中的User-Agent屬性
method.addRequestHeader("User-Agent", "Mozilla/4.0");
HttpResponse response = new HttpResponse();

try {
httpclient.executeMethod(method);
if (request.getResultType().equals(HttpResultType.STRING)) {
response.setStringResult(method.getResponseBodyAsString());
} else if (request.getResultType().equals(HttpResultType.BYTES)) {
response.setByteResult(method.getResponseBody());
}
response.setResponseHeaders(method.getResponseHeaders());
} catch (UnknownHostException ex) {

return null;
} catch (IOException ex) {

return null;
} catch (Exception ex) {

return null;
} finally {
method.releaseConnection();
}
return response;
}
當(dāng)然我們需要在new HttpProtocolHandler這個(gè)類的時(shí)候創(chuàng)建一個(gè)線程安全的HTTP連接池,為什么要線程安全,下文會(huì)有提示。我們把這個(gè)步驟放到私有的構(gòu)造方法當(dāng)中:
private HttpProtocolHandler() {  
connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.getParams().setDefaultMaxConnectionsPerHost(defaultMaxConnPerHost);
connectionManager.getParams().setMaxTotalConnections(defaultMaxTotalConn);

IdleConnectionTimeoutThread ict = new IdleConnectionTimeoutThread();
ict.addConnectionManager(connectionManager);
ict.setConnectionTimeout(defaultIdleConnTimeout);

ict.start();
}
然后使用如下方法來(lái)使其他類能使用getInstance()方法就獲得HttpProtocolHandler這個(gè)類的實(shí)例對(duì)象,并且是線程安全的:
private static HttpProtocolHandler httpProtocolHandler                 = new HttpProtocolHandler();  

/**
* 工廠方法
*
* @return
*/
public static HttpProtocolHandler getInstance() {
return httpProtocolHandler;
}
此類當(dāng)中還有一些屬性,用來(lái)設(shè)置http連接的超時(shí)時(shí)間,連接數(shù)等參數(shù):
private static String              DEFAULT_CHARSET                     = "GBK";  

/** 連接超時(shí)時(shí)間,由bean factory設(shè)置,缺省為8秒鐘 */
private int defaultConnectionTimeout = 8000;

/** 回應(yīng)超時(shí)時(shí)間, 由bean factory設(shè)置,缺省為30秒鐘 */
private int defaultSoTimeout = 30000;

/** 閑置連接超時(shí)時(shí)間, 由bean factory設(shè)置,缺省為60秒鐘 */
private int defaultIdleConnTimeout = 60000;

private int defaultMaxConnPerHost = 30;

private int defaultMaxTotalConn = 80;

/** 默認(rèn)等待HttpConnectionManager返回連接超時(shí)(只有在達(dá)到最大連接數(shù)時(shí)起作用):1秒*/
private static final long defaultHttpConnectionManagerTimeout = 3 * 1000;

/**
* HTTP連接管理器,該連接管理器必須是線程安全的.(如何設(shè)置線程安全上文已經(jīng)寫了)
*/
private HttpConnectionManager connectionManager;
此類當(dāng)中還有HttpClient和HttpResponse這兩個(gè)類,這兩個(gè)類主要是對(duì)HTTP請(qǐng)求的封裝和返回http的相應(yīng)消息。這兩個(gè)類就不在這里講了,就是兩個(gè)pojo類,HttpClient里面封裝了請(qǐng)求需要的屬性比如字符集,請(qǐng)求method,超時(shí)時(shí)間等,HttpResponse里面是響應(yīng)頭和返回結(jié)構(gòu)的封裝。
最后一個(gè)是支付寶各接口構(gòu)造類AlipayService.java,
/**  
* 支付寶提供給商戶的服務(wù)接入網(wǎng)關(guān)URL(新)
*/
private static final String ALIPAY_GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";

/**
* 構(gòu)造快捷登錄接口
* @param sParaTemp 請(qǐng)求參數(shù)集合
* @return 表單提交HTML信息
*/
public static String alipay_auth_authorize(Map<String, String> sParaTemp) {

//增加基本配置
sParaTemp.put("service", "alipay.auth.authorize");
sParaTemp.put("target_service", "user.auth.quick.login");
sParaTemp.put("partner", AlipayConfig.partner);
sParaTemp.put("return_url", AlipayConfig.return_url);
sParaTemp.put("_input_charset", AlipayConfig.input_charset);

String strButtonName = "確認(rèn)";

return AlipaySubmit.buildForm(sParaTemp, ALIPAY_GATEWAY_NEW, "get", strButtonName);
}

/**
* 用于防釣魚,調(diào)用接口query_timestamp來(lái)獲取時(shí)間戳的處理函數(shù)
* 注意:遠(yuǎn)程解析XML出錯(cuò),與服務(wù)器是否支持SSL等配置有關(guān)
* @return 時(shí)間戳字符串
* @throws IOException
* @throws DocumentException
* @throws MalformedURLException
*/
public static String query_timestamp() throws MalformedURLException,
DocumentException, IOException {

//構(gòu)造訪問(wèn)query_timestamp接口的URL串
String strUrl = ALIPAY_GATEWAY_NEW + "service=query_timestamp&partner=" + AlipayConfig.partner;
StringBuffer result = new StringBuffer();

SAXReader reader = new SAXReader();
Document doc = reader.read(new URL(strUrl).openStream());

List<Node> nodeList = doc.selectNodes("//alipay/*");

for (Node node : nodeList) {
// 截取部分不需要解析的信息
if (node.getName().equals("is_success") && node.getText().equals("T")) {
// 判斷是否有成功標(biāo)示
List<Node> nodeList1 = doc.selectNodes("//response/timestamp/*");
for (Node node1 : nodeList1) {
result.append(node1.getText());
}
}
}

return result.toString();
}
到這里支付寶的登錄接口基本上已經(jīng)結(jié)束了,講的不是很詳細(xì)

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
支付開發(fā)填坑記之支付寶
反射的應(yīng)用 將form表單的數(shù)據(jù)自動(dòng)封裝為對(duì)象
JAVA通過(guò)HTTP訪問(wèn):Post+Get方式
android 將int轉(zhuǎn)byte,byte轉(zhuǎn)int的兩種方法
java版+支付寶支付和微信支付(一)
給內(nèi)核模塊傳遞參數(shù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服