由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来

,希望能对.net开发者服务端网站更快的集成微信app支付。

1.开发所需资料:微信开放平台应用的appid以及appsecert,商户平台的商户号以及api安全里面里面设置的key,详见 微信支付账户相关信息;

2.微信开发者平台完善应用平台的相关信息,android应用签名必须用打包签名过的发布版本apk(这一步很重用),包名必须一致,可以用微信提供的签名工具获得,签名工具下载地址https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成(来源微信支付开发文档):

商户系统和微信支付支付系统主要交互:

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。商户后台收到订单时需要调用微信的同意下单接口,生成预支付单;

C#大概代码如下(相关代码参考自JeffreySu/WeiXinMPSDK ):

private WechatPayResult generatePayResult(string mchappid,string mchid
,string body,string orderno,int total,string ip,string notify,string mchkey,string nonce)
{
DateTime start = DateTime.Now,end= DateTime.Now.AddMinutes();
var xmlDataInfo = new TenPayV3UnifiedorderRequestData(mchappid
,mchid, body, orderno, total
,ip,notify, TenPayV3Type.APP
, null, mchkey, nonce, null,start,end);
var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
return new WechatPayResult
{
appid=mchappid,
body=body,
CreatedOn=DateTime.Now,
mch_id=mchid,
prepay_id=result.prepay_id,
spbill_create_ip=ip,
nonce_str=nonce,
timeStamp= TenPayV3Util.GetTimestamp(),
out_trade_no=orderno,
time_start=start,
time_expire=end,
total_fee=total,
trade_type=result.trade_type
};
}
  public class RequestHandler
{ public RequestHandler()
{
Parameters = new Hashtable();
} public RequestHandler(HttpContext httpContext)
{
Parameters = new Hashtable(); this.HttpContext = httpContext ?? HttpContext.Current; }
/// <summary>
/// 密钥
/// </summary>
private string Key; protected HttpContext HttpContext; /// <summary>
/// 请求的参数
/// </summary>
protected Hashtable Parameters; /// <summary>
/// debug信息
/// </summary>
private string DebugInfo; /// <summary>
/// 初始化函数
/// </summary>
public virtual void Init()
{
}
/// <summary>
/// 获取debug信息
/// </summary>
/// <returns></returns>
public String GetDebugInfo()
{
return DebugInfo;
}
/// <summary>
/// 获取密钥
/// </summary>
/// <returns></returns>
public string GetKey()
{
return Key;
}
/// <summary>
/// 设置密钥
/// </summary>
/// <param name="key"></param>
public void SetKey(string key)
{
this.Key = key;
} /// <summary>
/// 设置参数值
/// </summary>
/// <param name="parameter"></param>
/// <param name="parameterValue"></param>
public void SetParameter(string parameter, string parameterValue)
{
if (parameter != null && parameter != "")
{
if (Parameters.Contains(parameter))
{
Parameters.Remove(parameter);
} Parameters.Add(parameter, parameterValue);
}
} /// <summary>
/// 当参数不为null或空字符串时,设置参数值
/// </summary>
/// <param name="parameter"></param>
/// <param name="parameterValue"></param>
public void SetParameterWhenNotNull(string parameter, string parameterValue)
{
if (!string.IsNullOrEmpty(parameterValue))
{
SetParameter(parameter, parameterValue);
}
} /// <summary>
/// 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名
/// </summary>
/// <param name="key">参数名</param>
/// <param name="value">参数值</param>
/// key和value通常用于填充最后一组参数
/// <returns></returns>
public virtual string CreateMd5Sign(string key, string value)
{
StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(Parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)Parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) !=
//&& "sign_type".CompareTo(k) != 0
&& "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
} sb.Append(key + "=" + value);
string sign = EncryptHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
//string sign = MD5UtilHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();
return sign;
}
public virtual string CreateMd5Sign()
{
StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(Parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)Parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) !=
//&& "sign_type".CompareTo(k) != 0
&& "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
}
string sign = EncryptHelper.GetMD5(sb.ToString().Substring(,sb.Length-), GetCharset()).ToUpper();
return sign;
}
/// <summary>
/// 输出XML
/// </summary>
/// <returns></returns>
public string ParseXML()
{
StringBuilder sb = new StringBuilder();
sb.Append("<xml>");
foreach (string k in Parameters.Keys)
{
string v = (string)Parameters[k];
if (v != null && Regex.IsMatch(v, @"^[0-9.]$"))
{ sb.Append("<" + k + ">" + v + "</" + k + ">");
}
else
{
sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
} }
sb.Append("</xml>");
return sb.ToString();
} /// <summary>
/// 设置debug信息
/// </summary>
/// <param name="debugInfo"></param>
public void SetDebugInfo(String debugInfo)
{
this.DebugInfo = debugInfo;
} public Hashtable GetAllParameters()
{
return this.Parameters;
} protected virtual string GetCharset()
{
if (this.HttpContext == null)
{
return Encoding.UTF8.BodyName;
} return this.HttpContext.Request.ContentEncoding.BodyName;
}
}
 /// <summary>
/// 微信支付提交的XML Data数据[统一下单]
/// </summary>
public class TenPayV3UnifiedorderRequestData
{
/// <summary>
/// 公众账号ID
/// </summary>
public string AppId { get; set; }
/// <summary>
/// 商户号
/// </summary>
public string MchId { get; set; }
/// <summary>
/// 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB",String(32)如:013467007045764
/// </summary>
public string DeviceInfo { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
public string NonceStr { get; set; }
/// <summary>
/// 签名类型,默认为MD5,支持HMAC-SHA256和MD5。(使用默认)
/// </summary>
public string SignType { get; set; }
/// <summary>
/// 商品信息
/// </summary>
public string Body { get; set; }
/// <summary>
/// 商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。
///cost_price Int 可选 32 订单原价,商户侧一张小票订单可能被分多次支付,订单原价用于记录整张小票的支付金额。当订单原价与支付金额不相等则被判定为拆单,无法享/受/优/惠。
/// receipt_id String 可选 32 商家小票ID
///goods_detail 服务商必填[]:
///└ goods_id String 必填 32 商品的编号
///└ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号
///└ goods_name String 可选 256 商品名称
///└ quantity Int 必填 32 商品数量
///└ price Int 必填 32 商品单价,如果商户有优惠,需传输商户优惠后的单价
///注意:单品总金额应&lt;=订单总金额total_fee,否则会无法享受优惠。
/// String(6000)
/// </summary>
public string Detail { get; set; }
/// <summary>
/// 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。String(127),如:深圳分店
/// </summary>
public string Attach { get; set; }
/// <summary>
/// 符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型。String(16),如:CNY
/// </summary>
public string FeeType { get; set; }
/// <summary>
/// 商家订单号
/// </summary>
public string OutTradeNo { get; set; }
/// <summary>
/// 商品金额,以分为单位(money * 100).ToString()
/// </summary>
public int TotalFee { get; set; }
/// <summary>
/// 用户的公网ip,不是商户服务器IP
/// </summary>
public string SpbillCreateIP { get; set; }
/// <summary>
/// 订单生成时间,最终生成格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则。
/// 如果为空,则默认为当前服务器时间
/// </summary>
public string TimeStart { get; set; }
/// <summary>
/// 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
/// 注意:最短失效时间间隔必须大于5分钟。
/// 留空则不设置失效时间
/// </summary>
public string TimeExpire { get; set; }
/// <summary>
/// 商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠。String(32),如:WXG
/// </summary>
public string GoodsTag { get; set; }
/// <summary>
/// 接收财付通通知的URL
/// </summary>
public string NotifyUrl { get; set; }
/// <summary>
/// 交易类型
/// </summary>
public TenPayV3Type TradeType { get; set; }
/// <summary>
/// trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
/// String(32),如:12235413214070356458058
/// </summary>
public string ProductId { get; set; }
/// <summary>
/// 上传此参数no_credit--可限制用户不能使用信用卡支付
/// </summary>
public string LimitPay { get; set; }
/// <summary>
/// 用户的openId
/// </summary>
public string OpenId { get; set; } /// <summary>
///
/// </summary>
public string Key { get; set; } public readonly RequestHandler PackageRequestHandler;
public readonly string Sign; /// <summary>
///
/// </summary>
/// <param name="appId"></param>
/// <param name="mchId"></param>
/// <param name="body"></param>
/// <param name="outTradeNo"></param>
/// <param name="totalFee">单位:分</param>
/// <param name="spbillCreateIp"></param>
/// <param name="notifyUrl"></param>
/// <param name="tradeType"></param>
/// <param name="openid"></param>
/// <param name="key"></param>
/// <param name="nonceStr"></param>
/// <param name="deviceInfo">自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB",String(32)如:013467007045764</param>
/// <param name="timeStart">订单生成时间,如果为空,则默认为当前服务器时间</param>
/// <param name="timeExpire">订单失效时间,留空则不设置失效时间</param>
/// <param name="detail">商品详细列表</param>
/// <param name="attach">附加数据</param>
/// <param name="feeType">符合ISO 4217标准的三位字母代码,默认人民币:CNY</param>
/// <param name="goodsTag">商品标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠。String(32),如:WXG</param>
/// <param name="productId">trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。String(32),如:12235413214070356458058</param>
/// <param name="limitPay">是否限制用户不能使用信用卡支付</param>
public TenPayV3UnifiedorderRequestData(string appId, string mchId, string body, string outTradeNo, int totalFee, string spbillCreateIp,
string notifyUrl, TenPayV3Type tradeType, string openid, string key, string nonceStr,
string deviceInfo = null, DateTime? timeStart = null, DateTime? timeExpire = null,
string detail = null, string attach = null, string feeType = "CNY", string goodsTag = null, string productId = null, bool limitPay = false)
{
AppId = appId;
MchId = mchId;
DeviceInfo = deviceInfo;
NonceStr = nonceStr;
SignType = "MD5";
Body = body ?? "";
Detail = detail;
Attach = attach;
OutTradeNo = outTradeNo;
FeeType = feeType;
TotalFee = totalFee;
SpbillCreateIP = spbillCreateIp;
TimeStart = (timeStart ?? DateTime.Now).ToString("yyyyMMddHHmmss");
TimeExpire = timeExpire.HasValue ? timeExpire.Value.ToString("yyyyMMddHHmmss") : null;
GoodsTag = goodsTag;
NotifyUrl = notifyUrl;
TradeType = tradeType;
ProductId = productId;
LimitPay = limitPay ? "no_credit" : null;
OpenId = openid;
Key = key; #region 设置RequestHandler //创建支付应答对象
PackageRequestHandler = new RequestHandler(null);
//初始化
PackageRequestHandler.Init(); //设置package订单参数
//以下设置顺序按照官方文档排序,方便维护:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
PackageRequestHandler.SetParameter("appid", this.AppId); //公众账号ID
PackageRequestHandler.SetParameter("mch_id", this.MchId); //商户号
PackageRequestHandler.SetParameterWhenNotNull("device_info", this.DeviceInfo); //自定义参数
PackageRequestHandler.SetParameter("nonce_str", this.NonceStr); //随机字符串
PackageRequestHandler.SetParameterWhenNotNull("sign_type", this.SignType); //签名类型,默认为MD5
PackageRequestHandler.SetParameter("body", this.Body); //商品信息
PackageRequestHandler.SetParameterWhenNotNull("detail", this.Detail); //商品详细列表
PackageRequestHandler.SetParameterWhenNotNull("attach", this.Attach); //附加数据
PackageRequestHandler.SetParameter("out_trade_no", this.OutTradeNo); //商家订单号
PackageRequestHandler.SetParameterWhenNotNull("fee_type", this.FeeType); //符合ISO 4217标准的三位字母代码,默认人民币:CNY
PackageRequestHandler.SetParameter("total_fee", this.TotalFee.ToString()); //商品金额,以分为单位(money * 100).ToString()
PackageRequestHandler.SetParameter("spbill_create_ip", this.SpbillCreateIP); //用户的公网ip,不是商户服务器IP
PackageRequestHandler.SetParameterWhenNotNull("time_start", this.TimeStart); //订单生成时间
PackageRequestHandler.SetParameterWhenNotNull("time_expire", this.TimeExpire); //订单失效时间
PackageRequestHandler.SetParameterWhenNotNull("goods_tag", this.GoodsTag); //商品标记
PackageRequestHandler.SetParameter("notify_url", this.NotifyUrl); //接收财付通通知的URL
PackageRequestHandler.SetParameter("trade_type", this.TradeType.ToString()); //交易类型
PackageRequestHandler.SetParameterWhenNotNull("product_id", this.ProductId); //trade_type=NATIVE时(即扫码支付),此参数必传。
PackageRequestHandler.SetParameterWhenNotNull("limit_pay", this.LimitPay); //上传此参数no_credit--可限制用户不能使用信用卡支付
PackageRequestHandler.SetParameter("openid", this.OpenId); //用户的openId,trade_type=JSAPI时(即公众号支付),此参数必传
Sign = PackageRequestHandler.CreateMd5Sign("key", this.Key);
PackageRequestHandler.SetParameter("sign", Sign); //签名
#endregion
}
}

统一下单

 /// <summary>
/// 统一支付接口
/// 统一支付接口,可接受JSAPI/NATIVE/APP 下预支付订单,返回预支付订单号。NATIVE 支付返回二维码code_url。
/// </summary>
/// <param name="dataInfo">微信支付需要post的Data数据</param>
/// <param name="timeOut"></param>
/// <returns></returns>
public static UnifiedorderResult Unifiedorder(TenPayV3UnifiedorderRequestData dataInfo, int timeOut = Config.TIME_OUT)
{
var urlFormat = "https://api.mch.weixin.qq.com/pay/unifiedorder";
var data = dataInfo.PackageRequestHandler.ParseXML();//获取XML
//throw new Exception(data.HtmlEncode());
MemoryStream ms = new MemoryStream();
var formDataBytes = data == null ? new byte[] : Encoding.UTF8.GetBytes(data);
ms.Write(formDataBytes, , formDataBytes.Length);
ms.Seek(, SeekOrigin.Begin);//设置指针读取位置 var resultXml = RequestUtility.HttpPost(urlFormat, null, ms, timeOut: timeOut);
return new UnifiedorderResult(resultXml);
}

统一支付接口

步骤2:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay,签名的字段数量必须跟你app调起微信支付所传的参数一致:

 /// <summary>
/// 生成微信app支付前面
/// </summary>
/// <param name="appId"></param>
/// <param name="timeStamp"></param>
/// <param name="nonceStr"></param>
/// <param name="package"></param>
/// <param name="key"></param>
/// <param name="partnerid"></param>
/// <param name="prepayid"></param>
/// <param name="signType"></param>
/// <returns></returns>
public static string GetAppPaySign(string appId
, string timeStamp, string nonceStr, string package,
string key,string partnerid,string prepayid,string signType = "MD5"
)
{
RequestHandler paySignReqHandler = new RequestHandler(null);
paySignReqHandler.SetParameter("appid", appId.Trim());
paySignReqHandler.SetParameter("timestamp", timeStamp.Trim());
paySignReqHandler.SetParameter("noncestr", nonceStr.Trim());
paySignReqHandler.SetParameter("partnerid", partnerid);
paySignReqHandler.SetParameter("prepayid", prepayid);
paySignReqHandler.SetParameter("package", package.Trim());
//paySignReqHandler.SetParameter("signtype", "MD5");
var paySign = paySignReqHandler.CreateMd5Sign("key", key);
return paySign;
}

生成微信app支付签名

步骤3:商户APP调起微信支付。详细介绍参见微信支付官方文档

关键代码如下:

 public   static  IWXAPI api;
api= WXAPIFactory.createWXAPI(this, Constants.APP_ID,true);
api.registerApp(Constants.APP_ID);
Result result = JSON.parseObject(bytes, Result.class);
if (null != result) {
if (result.isSuccess()) {
prepay prepay = JSON.parseObject(result.getData().toString(), prepay.class);
PayReq request = new PayReq();
request.appId = prepay.getAppid();
request.partnerId =prepay.getPartnerid();
request.prepayId= prepay.getPrepayid();
request.packageValue = prepay.getPackages();
request.nonceStr= prepay.getNoncestr();
request.timeStamp=prepay.getTimestamp();
request.sign= prepay.getSign();
api.sendReq(request);
}
}

android调起支付相关代码

其中result.getData()表示服务端返回的预支付订单的相关参数,用这参数调用微信支付,该activity必须实现接口IWXAPIEventHandler,并实现

@Override
public void onResp(BaseResp baseResp) {
if(baseResp.getType()== ConstantsAPI.COMMAND_PAY_BY_WX){
Log.d("dd","onPayFinish,errCode="+baseResp.errCode);
}
}
用于判断微信支付结果,安全起见,建议微信app回调后请求商户api相关接口确定支付结果
支付成功时微信后台会请求生成预支付单时传递的通知url(即payProvider.TenpayNotify)通知商户支付结果,商户后台校验相关信息
 [AllowAnonymous]
public ActionResult PayResult()
{
ResponseHandler resHandler = new ResponseHandler(null);
string return_code = resHandler.GetParameter("return_code");
string return_msg = resHandler.GetParameter("return_msg");
string res = null;
EngineContext.Current.Resolve<ILogger>().Information("收到微信支付通知"+resHandler.ParseXML());
//EngineContext.Current.Resolve<ILoggingService>().Write(LogType.Pay, resHandler.ParseXML());
string orderno = resHandler.GetParameter("out_trade_no");
string payno = resHandler.GetParameter("transaction_id");
string nonce_str = resHandler.GetParameter("nonce_str");
var order = _wechatService.GetWechatPayResult(orderno);
if (order != null)
{
var first = order.FirstOrDefault(r => r.nonce_str == nonce_str);
if (first != null)
{
var payProvider = _wechatService.GetWechatPayProvider(first.appid);
resHandler.SetKey(payProvider.MchKey);
if (resHandler.IsTenpaySign())
{
if (return_code == TenPayTypeResult.SUCCESS.ToString())
{
int totaled= int.Parse(resHandler.GetParameter("total_fee"));
if (totaled == first.total_fee)
{
first.IsSuccess = true;
first.time_end = DateTime.Now;
first.total_fee_ed = int.Parse(resHandler.GetParameter("total_fee"));
first.transaction_id = payno;
first.Content = resHandler.ParseXML();
_wechatService.UpdateWechatPayResult(first);
EngineContext.Current.Resolve<IEventPublisher>().Publish(resultEvent);
}else
{
EngineContext.Current.Resolve<ILogger>().Information("微信支付金额与订单金额不匹配" + resHandler.ParseXML());
} }
}
} //验证请求是否从微信发过来(安全)
string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
return Content(xml, "text/xml");
}

微信回调通知参考代码

微信支付官方文档

微信.NET集成可参考现有轮子 JeffreySu/WeiXinMPSDK

微信app支付android客户端以及.net服务端实现的更多相关文章

  1. 微信app支付(android端+java后台)

    本文讲解使用微信支付接口完成在android开发的原生态app中完成微信支付功能, 文章具体讲解了前端android如何集成微信支付功能以及后台如何组装前端需要支付信息, 话不多话, 具体看文章内容吧 ...

  2. 微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)

    转自:http://www.kwstu.com/ArticleView/netmvc_201511132050268716 最近开发手机app需要实现移动支付功能,由于考虑支付安全将微信支付生成签名写 ...

  3. Android客户端与PHP服务端交互(一)---框架概述

    背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事 ...

  4. Android客户端与PC服务端、android服务端通过WiFi通信

    前期准备:我的是Linux Mint操作系统(总之折腾的过程中怀疑过是不是系统的问题),首先是要创建wifi热点给android手机使用,这个时候笔记本作为通信的服务器端,android手机作为客户端 ...

  5. android客户端向java服务端post发送json

    android 端: private void HttpPostData() {        try { HttpClient httpclient = new DefaultHttpClient( ...

  6. Android客户端转换php服务端获取的时间戳的转换

    今天在用JSON获取后台的数据的时候,发现一个奇怪的现象就是返回来的时间戳都是1970年这样的,很是纠结,最后发现时php和Java中时间的格式不一样造成的,所以我们本地客户端要做一个转换: /** ...

  7. Android版-微信APP支付

    首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...

  8. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  9. asp.net core 微信APP支付(扫码支付,H5支付,公众号支付,app支付)之4

    微信app支付需要以下参数,类封装如下 public class WxPayModel { /// <summary> /// 应用ID /// </summary> publ ...

随机推荐

  1. jquery中append与appendTo方法区别

    1. append(content)方法 方法作用:向每个匹配的元素内部追加内容. 参数介绍:content (<Content>): 要追加到目标中的内容. 用法示例: HTML代码为& ...

  2. 常用的一些js和css

    /*给一组li里面写入12345.....*/ $("li").html(function(idx){ return idx+1; }) css限制文字字数: white-spac ...

  3. if else 与switch case判断

    基础数据类型(四类八种 ) 不能为null. 整数型 byte 取值范围2的8次方 short 取值范围2的16次方 int 取值范围2的32次方 一般用int long 取值范围2的64次方 浮点型 ...

  4. php 极简框架ES发布(代码总和不到 400 行)

    ES 框架简介 ES 是一款 极简,灵活, 高性能,扩建性强 的php 框架. 未开源之前在商业公司 经历数年,数个高并发网站 实践使用! 框架结构 整个框架核心四个文件,所有文件加起来放在一起总行数 ...

  5. hibernate的对象状态分析

    开发框架 springMVC hibernate5.0.1 hibernate三种状态 Hibernate定义并支持下列对象状态(state): 临时状态(Transient) 当new一个实体对象后 ...

  6. 如何使用OLAMI自然语言理解开放平台API制作自己的智能对话助手小程序

    我们经常在电影中看到机器和人对答如流,随着越来越多自然语言开放平台的出现,IT爱好者制作一个自己的APP或者小玩具等逐渐可以变为现实. 自然语言对话即你的APP或者你制作的工具.机器人等能够对用户输入 ...

  7. Java之面向对象例子(三) 多态,重写,重载,equals()方法和toString()方法的重写

    重写(继承关系) 子类得成员方法和父类的成员方法,方法名,参数类型,参数个数完全相同,这就是子类的方法重写了父类的方法. 重载 在一个类里有两个方法,方法名是完全一样的,参数类型或参数个数不同. 例子 ...

  8. Linux基础(七)

    一.nfs服务 nfs(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源.常用于Linux系统之间的文件共享. nfs在文件传送过程中依赖r ...

  9. 【转载】Android 开发 命名规范

    原文地址:http://www.cnblogs.com/ycxyyzw/p/4103284.html 标识符命名法标识符命名法最要有四种: 1 驼峰(Camel)命名法:又称小驼峰命名法,除首单词外, ...

  10. 【原创】IE11惊现无厘头Crash BUG(三招搞死你的IE11,并提供可重现代码)!

    前言 很多人都知道我们在做FineUI控件库,而且我们也做了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便大家查阅: 分享IE7一个神奇的BUG(不是封闭 ...