php的威富通支付接口,威富通支付接口 - osc_hlr8sqnv的个人空间 - OSCHINA - 中文开源技术交流社区...
/*** 直接调用威富通支付通道*/@Overridepublic PayBaseBean swiftpassPay(PayBaseBean payBaseBean,Mapconfig, String token,WeixinAccountVO weixinAccountVO) {
Map map = new HashMap();//签名
try{
String mchId= config.get("MCH_ID");
String mchKey= config.get("MCH_KEY");
String notifyUrl= config.get("NOTIFY_URL");
String callBackUrl= config.get("CALL_BACK_URL");if(StringUtils.isEmpty(notifyUrl) || StringUtils.isEmpty(callBackUrl) || StringUtils.isEmpty(mchKey) ||StringUtils.isEmpty(mchId)){
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage("invalid parameter");
logger.info("签名前获取参数错误,请检查配置");returnpayBaseBean;
}
map.put("sub_appid",weixinAccountVO.getAccountAppid());//微信公众号开发者appid
map.put("service", "pay.weixin.jspay");//接口类型
map.put("mch_id", mchId);//威富通商户号
map.put("is_raw", "1");//是否原生态(1:是; 0:否)
map.put("out_trade_no", payBaseBean.getOutTradeNo());//商户订单号
map.put("body", payBaseBean.getBody());//商品描述//测试号
if("7551000001".equals(config.get("MCH_ID"))){
map.put("total_fee", getTotal_fee(0.01));//总金额
}else{
map.put("sub_openid", payBaseBean.getOpenId());//用户openid
map.put("total_fee", getTotal_fee(payBaseBean.getTotalFee()));//总金额
}//map.put("attach", payBaseBean.getAttach());//附加信息
map.put("mch_create_ip", getMchCreateIp());//终端IP
map.put("notify_url",payBaseBean.getNotifyUrl());//通知地址//map.put("notify_url", "http://119.147.81.22/pinganWeb/"+ token +"/notify.html");//通知地址
map.put("callback_url", callBackUrl + token + payBaseBean.getCallbackUrl());//前台回调地址
map.put("nonce_str", getNonceStr());//随机字符串
logger.info("签名前密钥字符串:" +mchKey);
String signStr= SignUtil.getSign(map, mchKey);//排序拼装签名字符串
logger.info("签名前字符串:" +signStr);
String sign=SignUtil.MD5Encode(signStr).toUpperCase();
logger.info("签名后字符串:" +sign);
map.put("sign", sign);
map.remove("callback_url");
map.put("callback_url", "");//前台回调地址
} catch(Exception e) {
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage("sign error" +e.getMessage());
logger.info("签名时异常,请检查签名方法");returnpayBaseBean;
}//交互
try{
StringBuffer sb= newStringBuffer();
sb.append("");
SignUtil.mapToXMLTest2(map, sb);
sb.append("");
logger.info("发送请求:" +sb.toString());
payBaseBean.setSendData(sb.toString());
payBaseBean.setPayUrl(config.get("SWIFTPASS_INIT_URL"));//支付初始地址
HttpRequest pay = newHttpRequest();
pay.request(payBaseBean);
}catch(Exception e) {
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage("pay error");
logger.info("支付通讯异常,请检查支付通讯方法");returnpayBaseBean;
}//验签
try{
String recData=payBaseBean.getRecviceData();
logger.info("收到数据:" +recData);
Map recMap =SignUtil.stringToXmlToMap(recData);
String status= (String) recMap.get("status");if("0".equals(status)){
String recSign= (String) recMap.get("sign");
recMap.remove("sign");
String signStr= SignUtil.getSign(recMap,config.get("MCH_KEY"));//排序拼装签名字符串
logger.info("验签前字符串:" +signStr);
String sign=SignUtil.MD5Encode(signStr).toUpperCase();
logger.info("验签后字符串:" +sign);//校验签名数据
if(recSign.equals(sign)){
String resultCode= (String) recMap.get("result_code");if("0".equals(resultCode)){//获取是否原生处理
String isRaw = config.get("IS_RAW");if(isRaw.equals("1")){
JSONObject o= newJSONObject();
String pay_info= (String)recMap.get("pay_info");
logger.info("获取pay_info数据: "+pay_info);
JSONObject jsonObj=JSONObject.parseObject(pay_info);
o.put("appId",jsonObj.get("appId").toString());//公众号名称
o.put("package", jsonObj.get("package").toString());//订单详情扩展字符串
o.put("timeStamp", jsonObj.get("timeStamp").toString());//时间戳,自1970年以来的秒数
o.put("nonceStr", jsonObj.get("nonceStr").toString());//随机串
o.put("signType", jsonObj.get("signType").toString());// //微信签名方式:MD5
o.put("paySign", jsonObj.get("paySign").toString());//微信签名
o.put("callback_url", config.get("CALL_BACK_URL") + token +payBaseBean.getCallbackUrl());
cacheService.put(RAW_PAY_KEY+payBaseBean.getOutTradeNo(), o.toJSONString(),2, TimeUnit.HOURS);
payBaseBean.setResultCode(PubConst.PAY_STATE_OK);
payBaseBean.setSendData(config.get("NOTIFY_URL")+"wisdom/rawpay.html?tokenId=" +payBaseBean.getOutTradeNo());
}else{//正常直接访问地址
String token_id = (String) recMap.get("token_id");
payBaseBean.setResultCode(PubConst.PAY_STATE_OK);
payBaseBean.setSendData(config.get("SWIFTPASS_PAY_URL") + "?token_id=" +token_id);
}//一码通返回pay_info
String pay_info = (String) recMap.get("pay_info");
payBaseBean.setPayInfo(pay_info);
}else{
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage((String) recMap.get("err_msg"));
}
}else{
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage("验签失败,请检查报文。");
}
}else{
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage((String) recMap.get("message"));
}
}catch(Exception e) {
payBaseBean.setResultCode(PubConst.PAY_STATE_FAIL);
payBaseBean.setResultMessage("check sign error");
logger.info("通讯完成,验签异常,请检查支付后验签方法");returnpayBaseBean;
}returnpayBaseBean;
}
工具类
package cn.rmt.wxbase.wxpay;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class SignUtil {
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "a", "b", "c", "d", "e", "f"};
/**
* 签名算法
* @param o 要参与签名的数据对象
* @return 签名
* @throws IllegalAccessException
*/
public static String getSign(Map map,String key){
ArrayList list = new ArrayList();
for(Map.Entry entry:map.entrySet()){
if(entry.getValue()!="" && null != entry.getValue()){
list.add(entry.getKey() + "=" + entry.getValue() + "&");
}
}
int size = list.size();
String [] arrayToSort = list.toArray(new String[size]);
Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < size; i ++) {
sb.append(arrayToSort[i]);
}
String result = sb.toString();
result += "key=" + key;
return result;
}
/**
* MD5编码
* @param origin 原始字符串
* @return 经过MD5加密之后的结果
*/
public static String MD5Encode(String origin) {
String resultString = null;
try {
resultString = origin;
MessageDigest md = MessageDigest.getInstance("MD5");
resultString = byteArrayToHexString(md.digest(resultString.getBytes("utf-8")));
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
public static void mapToXMLTest2(Map map, StringBuffer sb) {
Set set = map.keySet();
for (Iterator it = set.iterator(); it.hasNext();) {
String key = (String) it.next();
Object value = map.get(key);
if (null == value)
value = "";
if (value.getClass().getName().equals("java.util.ArrayList")) {
ArrayList list = (ArrayList) map.get(key);
sb.append("");
for (int i = 0; i < list.size(); i++) {
HashMap hm = (HashMap) list.get(i);
mapToXMLTest2(hm, sb);
}
sb.append("" + key + ">");
} else {
if (value instanceof HashMap) {
sb.append("");
mapToXMLTest2((HashMap) value, sb);
sb.append("" + key + ">");
} else {
sb.append("" + value + "" + key + ">");
}
}
}
}
public static Map stringToXmlToMap(String recData){
Map retMap=new HashMap();
try {
StringReader sr = new StringReader(recData);
InputSource is = new InputSource(sr);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse(is);
doc.normalize();
Element root = doc.getDocumentElement();
NodeList nodeList = root.getChildNodes();
if(nodeList!=null){
for(int i=0;i
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
retMap.put(node.getNodeName(), node.getTextContent());
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return retMap;
}
}
微信支付通讯类
package cn.rmt.wxbase.wxpay;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import cn.rmt.wxbase.vo.PayBaseBean;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
/**
*
* 功能:微信支付数据通讯交互
* 作者:
* 日期:
* 版权所有:
*/
public class HttpRequest {
public void request(PayBaseBean payData) throws Exception {
HttpURLConnection connection = null;
OutputStream out = null;
BufferedReader reader = null;
String urlString = null;
try {
try {
urlString = payData.getPayUrl();
connection = (HttpURLConnection) (new URL(urlString)).openConnection();
} catch (Exception e) {
e.printStackTrace();
}
connection.setConnectTimeout(900*1000);
connection.setReadTimeout(900*1000);
connection.setRequestMethod("POST");
connection.setDoOutput(true);
//古井的模式要求为"YES"
connection.setRequestProperty("Intensoft-Request-Sign","NO");
connection.setRequestProperty("Content-Type", "application/x-fox");
connection.setRequestProperty("Content-Length", Integer.toString(payData.getSendData().getBytes().length));
// String sd=payData.replaceAll(">
// org.jeecgframework.core.util.LogUtil.info("发送数据:\r\n" + payData.getSendData());
try {
connection.connect();
out = connection.getOutputStream();
out.write(payData.getSendData().getBytes("UTF-8"));
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
StringBuffer receiveData = new StringBuffer();
// 分段收取
char[] receive = new char[1024];
int read = 0;
while ((read = reader.read(receive)) != -1)
receiveData.append(receive, 0, read);
payData.setRecviceData(receiveData.toString());
// org.jeecgframework.core.util.LogUtil.info("收到数据:\r\n" + receiveData.toString());
} catch (Exception e) {
e.printStackTrace();
}
} finally {
if (out != null)
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
if (reader != null)
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
if (connection != null)
connection.disconnect();
}
}
/**通联支付发送请求**/
public String reqPost(String urlString ,String urlParams) throws Exception {
HttpURLConnection connection = null;
OutputStream out = null;
BufferedReader reader = null;
StringBuffer receiveData = null ;
try {
connection = (HttpURLConnection) (new URL(urlString)).openConnection();
//SSL
System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return urlHostName.equals(session.getPeerHost());
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
//设置请求属性
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
if (connection instanceof HttpsURLConnection){
HttpsURLConnection httpsConn = (HttpsURLConnection)connection;
httpsConn.setSSLSocketFactory(SSLUtil.getInstance().getSSLSocketFactory());
} else if (connection instanceof HttpURLConnection){
HttpURLConnection httpConn = (HttpURLConnection)connection;
} else {
throw new Exception("不是http/https协议的url");
}
//建立连接
connection.connect();
//发送数据
out = connection.getOutputStream();
out.write(urlParams.getBytes("UTF-8"));
out.flush();
//获取数据
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
receiveData = new StringBuffer();
// 分段收取
char[] receive = new char[1024];
int read = 0;
while ((read = reader.read(receive)) != -1)
receiveData.append(receive, 0, read);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null)
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
if (reader != null)
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
if (connection != null)
connection.disconnect();
}
return receiveData.toString();
}
}
回调接口方法
@RequestMapping(value="/{token}/notify")
@RmtSecurityAuth(filterRule= RmtSecurityAuth.FilterRule.ANON)
public void notifyGet(@PathVariable String token,HttpServletRequest req,HttpServletResponse resp) {
logger.info("收到通知---->");
String respString = "error";
try {
Map map = parseXml(req);//威富通返回xml
logger.info("通知内容:" + map.toString());
if(map != null && map.size() > 0) {
WeixinAccountVO accountVO = weixinAccountService.getWeixinAccountByToken(token);
Map AccountConfigMap = weixinAccountConfigService.getAccountConfigList(accountVO.getId());
if (map.containsKey("sign")) {
if (!checkParam(map, AccountConfigMap.get("MCH_KEY"))) {//KEY
logger.info("---------验证签名不通过-------------");
} else {
String returnCode = map.get("status");
if (returnCode != null && PubConst.PAY_STATE_OK.equals(returnCode)) {
respString = "success";
String orderNo = map.get("out_trade_no");
logger.info("处理订单号:" + orderNo);
if (PubConst.PAY_STATE_SUCCESS.equals(map.get("result_code"))) {
//根据订单流水号查询中间表
WeixinMidPayInfoVO vo = weixinMidPayInfoService.findMidPayInfoByOrderNo(orderNo);
if (vo == null) {
logger.info("订单号" + orderNo + "不存在!");
} else {
String flag = vo.getIsRec();
if ("0".equals(flag)) {
logger.info("订单号" + orderNo + "已处理");
} else {
String[] pdid = vo.getOrderId().split(",");
if (pdid.length > 0) {
for (int i = 0; i < pdid.length; i++) {
WxSchoolWisdomPayInfoVO vos = wxSchoolWisdomPayInfoService.findById(pdid[i]);
List proIds = new ArrayList();//项目id
List dtlIds = new ArrayList();//明细id
//更新待缴费项目表状态
if ("" != vos.getpId() && null != vos.getpId()) {
String[] ids = vos.getpId().split(",");
for (int g = 0; g < ids.length; g++) {
String id = ids[g];
proIds.add(id);
}
for (int j = 0; j < proIds.size(); j++) {
WxSchoolWisdomPaymentDetailVO detailVO = new WxSchoolWisdomPaymentDetailVO();
detailVO = wxSchoolWisdomPaymentDetailService.findById(proIds.get(j));
detailVO.setTransactionId(orderNo);
detailVO.setPayState("0");//0:成功,1:未支付
detailVO.setPayEndDate(DateTools.getFormattingDateString(map.get("time_end"), "yyyyMMddHHmmss"));
wxSchoolWisdomPaymentDetailService.update(null, detailVO);
}
}
//明细表更新状态
if ("" != vos.getdId() && null != vos.getdId()) {
String[] ids = vos.getdId().split(",");
for (int f = 0; f < ids.length; f++) {
String id = ids[f];
dtlIds.add(id);
}
WxSchoolWisdomPaymentDetailInfoVO detailInfoVO = new WxSchoolWisdomPaymentDetailInfoVO();
for (int j = 0; j < dtlIds.size(); j++) {
detailInfoVO = wxSchoolWisdomPaymentDetailInfoService.findById(dtlIds.get(j));
detailInfoVO.setTransactionId(orderNo);
detailInfoVO.setPayState("0");//0:成功,1:未支付
detailInfoVO.setPayEndDate(DateTools.getFormattingDateString(map.get("time_end"), "yyyyMMddHHmmss"));
wxSchoolWisdomPaymentDetailInfoService.update(null, detailInfoVO);
}
}
}
//更新中间表状态
vo.setIsRec(PubConst.PAY_RESULT_OK);//已返回
vo.setRecState(map.get("result_code"));
vo.setTransactionId(map.get("transaction_id"));
vo.setPayEndDate(DateTools.getFormattingDateString(map.get("time_end"), "yyyyMMddHHmmss"));
weixinMidPayInfoService.saveOrUpdate(null, vo);
logger.info("订单号" + orderNo + "对应表名为:" + vo.getTableName());
//更新单据状态为已成功
WeixinMidPayInfoQueryParam param = new WeixinMidPayInfoQueryParam();
param.setWeixinMidPayInfo(vo);
int result = weixinMidPayInfoService.updateTableState(param);
if (result > 0) {
logger.info("订单号:" + orderNo + "支付成功。");
if (!StringUtils.isBlank(vo.getEndCallBackEvent())) {
//从地址获取PAY_END_CALL_BACK放到参数中,区分要实例化哪个对象
Map endParam = new HashMap();
endParam.put("transactionId", vo.getTransactionId());
endParam.put("tableName", vo.getTableName());
endParam.put(WeixinPayConst.PAY_END_CALL_BACK, vo.getEndCallBackEvent());
payEndCallBackService.doEndPay(endParam);
}
}
}
}
}
} else {
logger.info("订单号:" + orderNo + "支付失败");
}
} else {
logger.info("返回状态失败");
}
}
} else {
logger.info("无返回签名数据");
}
}else{
logger.info("返回数据异常");
}
resp.getWriter().write(respString);
} catch (Exception e) {
logger.error(e.getMessage());
try {
resp.getWriter().write(respString);
} catch (IOException e1) {
}
}
}
php的威富通支付接口,威富通支付接口 - osc_hlr8sqnv的个人空间 - OSCHINA - 中文开源技术交流社区...相关推荐
- 5.0 java集合框架中的接口collection属于_JAVA集合框架 - osc_cyo2dovg的个人空间 - OSCHINA - 中文开源技术交流社区...
一.为什么要使用集合 单个数据,可以用变量保存: 多个数据,可以用数组保存: 但是对于存储多个数据且数量不确定的情况,使用集合: 二.集合和数组的区别 (1)数组: 1.只能保存同一种类型的数据: 2 ...
- php面试题接口方面,php面试题6 - osc_xb4v1nhl的个人空间 - OSCHINA - 中文开源技术交流社区...
php面试题6 一.总结 二.php面试题6 写出你认为语言中的高级函数: 1)preg_replace() 2)preg_match() 3) ignore_user_abort() 4) debu ...
- JAVA抽象类接口初始化块实验_抽象类和接口 - 逝水无痕7777的个人空间 - OSCHINA - 中文开源技术交流社区...
抽象类和接口 1.抽象类 抽象方法是只有方法签名,没有方法实现的方法.有抽象方法的类只能被定义成抽象类,抽象类可以没有抽象方法.抽象方法和抽象类必须使用abstract修饰符来定义. 抽象类不能被实例 ...
- android 基站定位 api,基站定位查询接口 - whoisliang的个人空间 - OSCHINA - 中文开源技术交流社区...
本站查询接口免费开放 所有免费接口禁止从移动设备端直接访问,请使用固定IP的服务器转发请求. 每5分钟限制查询300次,基站/WIFI/经纬度查询接口每日限制查询1000次,反向基站查询接口每日限制查 ...
- php支付宝扫码登录接口,支付宝支付接口 - musam的个人空间 - OSCHINA - 中文开源技术交流社区...
接入阿里支付宝其实不是很难,阿里提供了很全面的SDK供我们使用,我们只需调用API接口就可以完成支付功能,但是具体的业务还是需要我们自己编写,根据提供的文档记录一下简单的使用方式. 1.登录蚂蚁金服开 ...
- 百度音乐api+c语言,百度音乐接口api - osc_d87glhzv的个人空间 - OSCHINA - 中文开源技术交流社区...
百度音乐全接口 http://tingapi.ting.baidu.com/v1/restserver/ting 请求方式:GET 参数处理:format=json&calback=& ...
- java第三方支付接口(云通付)
个人学习总结,为java后台接口,不足之处请指教. 基于云通付实现的支付,所以先去云通付官网注册账号.得到相应的合作身份者PID.MD5密钥.商户号.(后面会用到) 下载相应jar包.将下载文件解压, ...
- 支付接口开发总结,支付宝接口、通联接口
主要知识点:会使用httpclient.理解回调和通知机制.理解session机制 支付宝开发主要就是三个接口:一个是下订单的接口. 这个接口中,先存储自己的订单业务逻辑. 然后根据自己支付宝注册成为 ...
- AI每日看点 | 吉利收购飞行汽车公司;传华为暂停向高通支付专利费;高通拒绝博通收购邀约
1. 吉利收购全球首家飞行汽车公司,将在中国量产 11月13日上午,浙江吉利控股集团有限公司与美国太力(Terrafugia)公司达成最终协议,收购太力公司的全部业务和资产.此项交易已获得包括美国外资 ...
- 聚合项目访问后台接口失败_聚合支付系统和免签支付系统对未来支付市场有哪些影响...
时势所趋,在如今支付通道不稳定的情况下,四方聚合支付的出现弥补了通道不稳的情况,四方聚合支付可以接入多个三方,实现在三方不稳的情况直接后台切换三方,实现一秒切换,还可以接入个人免签支付系统,实现商户实 ...
最新文章
- ASP.NET Web Pages – 文件简介
- CCS如何恢复到默认界面?
- Ktor 1.0发布:JetBrains推出的Kotlin Web框架
- java.io,PrintWriter可以用来创建一个文件并向本文文件写入数据
- 博弈论的局限性(博弈论的诡计)
- win7功能找不到信息服务器,win7系统找不到Internet信息服务的解决方法
- Java开发必须掌握的8种网站攻防技术
- 获取http地址如何从上面抓取图片_用 Python 自动抓取妹子图
- PG基于repmgr实现自动和手动故障切换
- 职业生涯最差绩效:M-
- vue 设置背景图地址_vue-生成自动铺满的背景图
- Python爬虫(三)--百度贴吧
- 《数据库系统概论》期末复习速成
- 5年做100款游戏是什么体验?“高产”开发者的10条心得
- celeste第二章_蔚蓝山Celeste全成就指南_蔚蓝山Celeste全成就获得方法_游戏堡
- 如何使用图灵机器人实现自动回复?
- 用QQ邮箱接收网易163企业邮箱的邮件
- Illegal character
- Netfilter 内核数据包过滤框架
- python面试题大全 以及 vue面试题(必看!!!)
热门文章
- 宽带噪声干扰 matlab,噪声干扰信号及Matlab仿真.doc
- matlab函数多个零点,MATLAB中求一个双变量函数的零点
- 基于QT和DCMTK的Dicom 图像浏览器---收尾二
- 支持javascript的ppt软件_有哪些辅助工具,可以让PowerPoint软件更强大?
- MySQL必知必会——数据库基础知识和MySQL基本使用
- 上海二手房8月排名:链家、悟空找房、中原、太平洋、我爱我家、易居、房天下、iwjw、房多多、房好多、q房网、、、...
- sqlldr mysql_sqlldr数据导入
- android 串流 ps4,就想要玩游戏!PS4有线串流到笔记本电脑实战
- 原生js实现图片验证码
- 深度优先遍历,广度优先遍历