在这个移动互联网快速发展的时代,手机已经成为人们生活或者出行之中必不可少的设备了,如今非常多城市的商户都能够採用支付宝,微信支付了。人们出门仅仅须要随身携带带手机。不用带大量现金就能够放心购物了。如今的非常多移动互联网产品都应用到移动支付功能。特别像电商平台。每天下单。支付就是他们处理的最复杂的业务逻辑。

作为一位Android开发者也必须应该懂得如何在自己所开发的应用中接入当今互联网非常流行的移动支付(银联,支付宝,微信)功能。所以此篇文章就来记录一下Android对于移动支付的一些开发步骤。

银联支付

简单介绍

银联手机支付控件(下面简称支付控件),主要为合作商户的手机client提供安全、便捷的支付服务。

用户通过在支付控件中输入银行卡卡号、手机号、password(借记卡和预付卡)或者CVN2(信用卡背面的数字)、有效期(信用卡)、验证码等要素完毕支付。

支付流程介绍

事实上银联,支付宝,微信的支付流程都差点儿相同,这里先说银联的支付流程。

流程图说明:

(1)用户在client中点击购买商品。client发起订单生成请求到商户后台;

(2)商户后台收到订单生成请求后,依照《手机控件支付产品接口规范》组织并推送订单信息至银联后台;

(3)银联后台接收订单信息并检查通过后。生成相应交易流水号(即TN),并回复交易流水号至商户后台(应答要素:交易流水号等);

(4)商户后台接收到交易流水号。将交易流水号返回给client;

(5)client通过交易流水号(TN)调用支付控件;

(6)用户在支付控件中输入相关支付信息后。由支付控件向银联后台发起支付请求。

(7)支付成功后,银联后台将支付结果通知给商户后台。

(8)银联将支付结果通知支付控件;

(9)支付控件显示支付结果并将支付结果返回给client;

在client的操作是(1)首先将商品的id传递给后台server,步骤(2)-(4)是server端完毕的。全部client不须要做其它操作。在本篇文章中直接产生一个模拟的流水号(TN),直接调用支付控件,完毕步骤(5)-(9)的操作。以下的代码就是一个简单的使用银联支付的demo

package com.example.unionpay;import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;import org.json.JSONException;
import org.json.JSONObject;import com.unionpay.UPPayAssistEx;import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;public class MainActivity extends Activity implements Callback,Runnable{/*** mMode參数解释: "00" - 启动银联正式环境 "01" - 连接银联測试环境*/private final String mMode = "01";//银联官方測试环境提供的訪问接口 可供測试使用。在实际开发其中能够替换成自己的服务端的接口地址 用于生产流水号(TN)private static final String TN_URL_01 = "http://101.231.204.84:8091/sim/getacptn";private Button btn;private Context mContext = null;private Handler mHandler = null;private ProgressDialog mLoadingDialog = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = this;mHandler = new Handler(this);btn = (Button) findViewById(R.id.submit);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//这里做详细的提交数据 訪问网络的操作mLoadingDialog = ProgressDialog.show(mContext,"", "正在努力的获取tn中,请稍候...",true); // 进度是否是不确定的,这仅仅和创建进度条有关// 步骤1:从网络開始,获取交易流水号即TNnew Thread(MainActivity.this).start();}});}@Overridepublic void run() {//这里主要做的是模拟将从商品ID传递给服务端 让服务端生产订单 最后银联后台生成支付的流水号//此处直接返回流水号String tn = null;InputStream is;try {String url = TN_URL_01;URL myURL = new URL(url);URLConnection ucon = myURL.openConnection();ucon.setConnectTimeout(120000);is = ucon.getInputStream();int i = -1;ByteArrayOutputStream baos = new ByteArrayOutputStream();while ((i = is.read()) != -1) {baos.write(i);}tn = baos.toString();is.close();baos.close();} catch (Exception e) {e.printStackTrace();}Message msg = mHandler.obtainMessage();msg.obj = tn;mHandler.sendMessage(msg);}@Overridepublic boolean handleMessage(Message msg) {//callback的回调函数if (mLoadingDialog.isShowing()) {mLoadingDialog.dismiss();}String tn = "";if (msg.obj == null || ((String) msg.obj).length() == 0) {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("错误提示");builder.setMessage("网络连接失败,请重试!");builder.setNegativeButton("确定",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}});builder.create().show();} else {tn = (String) msg.obj;//步骤2:通过银联工具类启动支付插件doStartUnionPayPlugin(this, tn, mMode);}return false;}public void doStartUnionPayPlugin(Activity activity, String tn, String mode) {UPPayAssistEx.startPay(activity, null, null, tn, mode);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {/************************************************** 步骤3:处理银联手机支付控件返回的支付结果************************************************/if (data == null) {return;}String msg = "";/** 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败。支付取消*/String str = data.getExtras().getString("pay_result");if (str.equalsIgnoreCase("success")) {// 支付成功后,extra中假设存在result_data。取出校验// result_data结构见c)result_data參数说明if (data.hasExtra("result_data")) {String result = data.getExtras().getString("result_data");try {JSONObject resultJson = new JSONObject(result);String sign = resultJson.getString("sign");String dataOrg = resultJson.getString("data");// 验签证书同后台验签证书// 此处的verify,商户需送去商户后台做验签boolean ret = verify(dataOrg, sign, mMode);if (ret) {// 验证通过后。显示支付结果msg = "支付成功!";} else {// 验证不通过后的处理// 建议通过商户后台查询支付结果msg = "支付失败!

"; } } catch (JSONException e) { } } else { // 未收到签名信息 // 建议通过商户后台查询支付结果 msg = "支付成功。"; } } else if (str.equalsIgnoreCase("fail")) { msg = "支付失败!"; } else if (str.equalsIgnoreCase("cancel")) { msg = "用户取消了支付"; } AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("支付结果通知"); builder.setMessage(msg); builder.setInverseBackgroundForced(true); // builder.setCustomTitle(); builder.setNegativeButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); } private boolean verify(String msg, String sign64, String mode) { // 此处的verify,商户需送去商户后台做验签 return true; } }

开发步骤(仅仅是我个人的习惯):

1.在xml文件里加入所须要的权限。这里直接复制粘贴就ok

   <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD" /><uses-permission android:name="android.permission.NFC" /><uses-feature android:name="android.hardware.nfc.hce"/>

2.在Application节点以下加入以下代码,我也不知道为毛,照着做就ok了

<uses-library android:name="org.simalliance.openmobileapi" android:required="false"/>

3.加入银联sdk中须要用到的支付的activity。注冊。

直接ctrl+c,ctrl+v就ok

        <activityandroid:name="com.unionpay.uppay.PayActivity"android:configChanges="orientation|keyboardHidden|keyboard"android:screenOrientation="portrait"android:excludeFromRecents="true"android:windowSoftInputMode="adjustResize"></activity><activityandroid:name="com.unionpay.UPPayWapActivity"android:configChanges="orientation|keyboardHidden|fontScale"android:screenOrientation="portrait"android:windowSoftInputMode="adjustResize" ></activity>

4.上面步骤完毕之后,你会看到manifest文件报错,提示要加入jar包,这就得去下载对应的jar加入响应的jar包和.so文件了,能够直接到我后面的demo里面拷贝。

也能够到官方网址上面去下载。

以下给了官网的步骤,好人做究竟。

别忘了还要将data.bin放入assets文件夹以下。详细这些请參考《中国银联手机支付控件接入指南》的操作

(1). 打开https://open.unionpay.com/
  (2). 下载规范和开发包。帮助中心-下载-产品接口规范-手机控件支付产品接口规范,帮助中心-下载-产品接口规范-手机控件支付产品技术开发包(安卓版的)。

5.开发我们自己的activity,处理client应该处理的逻辑。比如上面的mainActivity。

支付宝支付

蚂蚁金服也的确非常牛逼哈。支付宝支付的接入应该是在这三种支付接入方式中最简单的一种吧。有具体的文档和demo。

文档。sdk,demo下载地址。就支付宝,微信支付而言我们都须要注冊成为商家才干进行支付宝。微信支付方式的接入。一般的普通用户是没有这样的功能的,预计是微信或者支付宝要对这一部分人收取额外的费用 吧。所以要走这样一个流程。支付宝商家支付中心的申请也须要一堆审核。呵呵 ,假设你真的想去试试能够依照官网上的步骤一步一步走下去,以下所写的样例中。我用的是一个实际其中的商户ID。全部会真实的支付0.01元。还是依照我们习惯的一般步骤来看:

(1)在manifest文件里假如相关的系统权限。例如以下,直接copy就ok。

    <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />  

(2)注冊加入支付宝自己的接口,也就是支付的activity页面。

       <!-- alipay sdk begin --><activityandroid:name="com.alipay.sdk.app.H5PayActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind"android:windowSoftInputMode="adjustResize|stateHidden" ></activity><!-- alipay sdk end -->

(3)此时当然会提示找不到上面的H5PayActivity,此时就须要导入对应的jar包了。直接到官方demo里面拷贝alipaySdk.jar放入libs文件夹以下就ok。事实上此时别忘了将demo中的Base64.java。PayResult.java,SignUtils.java复制到我们的src文件夹下。免得我们又一次写一些关于签名加解密的类

上面就直接写自己的生成订单,提交订单,支付结果处理的逻辑就ok。

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;import com.alipay.sdk.app.PayTask;
import com.tz.aplipay.utils.Constants;
import com.tz.aplipay.utils.PayResult;
import com.tz.aplipay.utils.SignUtils;public class PayActivity extends Activity {//商户IDpublic static final String PARTNER = Constants.PARTNER;//商户收款账号public static final String SELLER = Constants.SELLER;//商户私钥//私钥用于对数据进行签名加密//公钥用于对签名进行验证public static final String RSA_PRIVATE = Constants.RSA_PRIVATE;private String name;private String price;private String desc;private final static int MESSAGE_PAY = 1;private Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case MESSAGE_PAY:String result = (String) msg.obj;PayResult payResult = new PayResult(result);//支付状态码String resultStatus = payResult.getResultStatus();if (TextUtils.equals(resultStatus, "9000")) {Toast.makeText(PayActivity.this, "支付成功", Toast.LENGTH_SHORT).show();}else if (TextUtils.equals(resultStatus, "8000")) {Toast.makeText(PayActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();}else{Toast.makeText(PayActivity.this, "支付失败", Toast.LENGTH_SHORT).show();}break;default:break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.pay);//获取商品的具体信息Intent intent = getIntent();name = intent.getStringExtra("name");price = intent.getStringExtra("price");desc = intent.getStringExtra("desc");TextView product_name = (TextView) findViewById(R.id.product_name);TextView product_price = (TextView) findViewById(R.id.product_price);TextView product_desc = (TextView) findViewById(R.id.product_desc);product_name.setText(name);product_price.setText(price);product_desc.setText(desc);}//支付public void pay(View btn){//1.构建订单数据String orderInfo = getOrderInfo(name, desc, price);//2.对订单进行签名String sign = sign(orderInfo);try {//转码sign = URLEncoder.encode(sign, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}//3.构建一个符合支付宝參数规范的订单数据final String payInfo = orderInfo + "&sign=\""+sign +"\"&sign_type=\"RSA\"" ;//4.调用支付接口new Thread(){public void run() {//支付任务PayTask task = new PayTask(PayActivity.this);String result = task.pay(payInfo);//依照支付宝的规则进行支付结果的解析Message msg = handler.obtainMessage(MESSAGE_PAY);msg.obj = result;handler.sendMessage(msg);}}.start();//5.处理支付结果}/*** 对订单进行签名* @param orderInfo* @return*/private String sign(String orderInfo) {return SignUtils.sign(orderInfo, RSA_PRIVATE);}/*** 构建订单信息* @param subject 商品名称* @param body 商品详情* @param price 商品金额* @return*/public String getOrderInfo(String subject, String body, String price) {// 签约合作者身份IDString orderInfo = "partner=" + "\"" + PARTNER + "\"";// 签约卖家支付宝账号orderInfo += "&seller_id=" + "\"" + SELLER + "\"";// 商户站点唯一订单号orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";// 商品名称orderInfo += "&subject=" + "\"" + subject + "\"";// 商品详情orderInfo += "&body=" + "\"" + body + "\"";// 商品金额orderInfo += "&total_fee=" + "\"" + price + "\"";// server异步通知页面路径orderInfo += "¬ify_url=" + "\"" + "http://notify.msp.hk/notify.htm"+ "\"";// 服务接口名称, 固定值orderInfo += "&service=\"mobile.securitypay.pay\"";// 支付类型, 固定值orderInfo += "&payment_type=\"1\"";// 參数编码。 固定值orderInfo += "&_input_charset=\"utf-8\"";// 设置未付款交易的超时时间// 默认30分钟。一旦超时。该笔交易就会自己主动被关闭。

// 取值范围:1m~15d。 // m-分钟,h-小时。d-天。1c-当天(不管交易何时创建,都在0点关闭)。 // 该參数数值不接受小数点,如1.5h,可转换为90m。 orderInfo += "&it_b_pay=\"30m\""; // extern_token为经过快登授权获取到的alipay_open_id,带上此參数用户将使用授权的账户进行支付 // orderInfo += "&extern_token=" + "\"" + extern_token + "\""; // 支付宝处理完请求后。当前页面跳转到商户指定页面的路径。可空 orderInfo += "&return_url=\"m.alipay.com\""; // 调用银行卡支付,需配置此參数,參与签名, 固定值 (须要签约《无线银行卡快捷支付》才干使用) // orderInfo += "&paymethod=\"expressGateway\""; return orderInfo; } /** * 产生一个包括时间的随机的订单号 * @return */ private String getOutTradeNo() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(); String key = sdf.format(date); Random random = new Random(); key = key + random.nextInt(); key = key.substring(0, 15); return key; } }

上述final类型的PARTNER对象就是在注冊商家时,支付宝分配陪你的唯一ID。

SELLER代表的是商家注冊时候拥有交易的支付宝账号。RSA_PRIVATE是你注冊时候支付宝分配给你的唯一私钥,配合支付宝的公钥实现数据的加解密操作。看看的我的constant文件。实际开发其中,必须将对应的值替换成你所申请的商户信息。不然以后打钱的时候都打到我这个支付宝其中了额。

public class Constants {public static final String PARTNER = "2088111984427922";public static final String SELLER = "zf@159cai.com";public static final String RSA_PRIVATE = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANcUPyx/lkokBOM1UfnFF1UckLs2Z2nh7RPMyhiMrats6LqsEhkCi4CiWS4ha6GuZcDtKzK2bfzd61IS1l6Ae4Qt+VZcdSpG+5vu875awBgiBCnbCP6YBm81vcAdSJYlOpizgS4JCuIalUqqaWN3hSP4tThuQcRAeHFwDi/ImJyDAgMBAAECgYBo2MnjG19cTSrEyB1qMRYqu34ihWbsSuKToGV0ij+vLaxWM8OuxXrT/lCTGF+rtaSM5BEG67+6YURyAhTWhLOw2mcEakFfVY0uTGadtsFODwHPkmDzL/kIhi99rB2gg0ota+FNVfd2oAmc//UvgHAeMA2bW+kxt9Y73XQE8yjbgQJBAP4kEemsgUtMo4y9lP8lkmwfK7pAWBiT2zajM6m///kfPG3NLJdJ4E4R026RBcZmL9WVxs2isX4o6TgLXtAmHpMCQQDYpwaT4RpkXIiSw124TlwrJF786c/OOtXm30kUuqWdMnbb6NFXDFMeeAPNN0bLLquR5X+XCIsroltpmLRi+VBRAkAuJGhoL9ztygVr2UQDK1Qxc1tiHqqgE8BaZDlOGcEk/ynemcD92vjx08S6r3QH+Ke4tM/6qA5n5I+rkEzvp+wnAkB2tG1CMSAIxTp/T1PWW/jcGn2BDYqycEIq0UR1ex6q1q+RJistCq+wDgnnMtYzFUskER6rXh8CtV5oqSaM5BVBAkBUqxfm8ro7eNagEnnWZidMrUIwesp1TQsQjtLFZTC9mVnpgLMj0IIaggojEBTQR6SvW7Sm7MqgqzYNUxlP0eoG";public static final String RSA_PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
}

在整个PayActivity中代码的132-181行实际上是构建订单信息的一个过程,事实上在现实中这个构建订单信息的过程是由client将商品的id传递给server端,server依据商家的一些信息,构建订单数据发送给支付宝的server,支付宝验证确定订单信息之后,才可以開始支付。

这里为了演示的简单,而且对后台server打搭建也不熟,所以就直接在client产生了订单信息。直接发送给支付宝。里面的參数的具体解释可以看以下的參数说明链接。

生成订单信息后就要对订单进行签名,最后构建符合支付宝參数规范的订单数据。之后调用支付接口PayTask。 假设手机上有支付宝client,就会直接打开支付宝client。假设么样安装支付宝client,就直接调用签名注冊的H5PayActivity进行登录支付操作。代码中的handler就是处理支付之后的各种返回结果。

微信支付

眼下没有实例来写微信支付。由于他也须要商家认证,全部先贴出微信支付的接入的 API

转载于:https://www.cnblogs.com/jzssuanfa/p/7380963.html

移动支付--银联,支付宝,微信(android)相关推荐

  1. JavaWEB后端支付银联,支付宝,微信对接

    注:本文来源于:<  JavaWEB后端支付银联,支付宝,微信对接  > JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所 ...

  2. java对接支付宝微信银联_JavaWEB后端支付银联,支付宝,微信对接

    JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所以对接部分做成了一个小模块. 先说下项目要求: 后端要对接银联无跳转Token支付,支 ...

  3. 建付支付即时到账源码免签支付支持支付宝微信拉卡拉等

    介绍: 建付支付系统即时到账源码_免签支付支持支付宝微信拉卡拉等等_带简单安装教程 源码说明:本站源码全部经过测试,配有前台及后台管理界面演示图,去除后门,绿色安全,希望对大家学习研究能有所帮助! 源 ...

  4. 西米支付:支付宝/微信支付/银联支付通道的接入介绍

    本文以电脑网站支付为例,着重对第三方支付通道的接入进行了分析,包括支付宝支付接入.微信支付接入及银联支付接入. 1.支付宝支付接入 支付宝支付能力主要有当面付.刷脸付.App支付.手机网站支付.电脑网 ...

  5. 支付精灵-支付宝-微信-聚合支付-给大家分享一个聚合支付的工具

    想必很多人个人开发者和我有同样的感触,想要在自己开发的app中接入微信支付和支付宝支付,仅仅是去申请支付接口就把我们挡在了门外,微信和支付宝都只对接企业的,那不是想逼死我们个人开发者吗?一开始使用过w ...

  6. 微信支付 postman_支付宝微信刷脸支付系统搭建服务商平台怎么做

    支付宝和微信只会把分润给到有分润系统的服务商(isv服务商) ,服务商分为俩种: 一.普通服务商 成为普通服务商任何人都可以申请 主要推广并非刷脸支付项目 针对的是钉钉 口碑 等业务 二.ISV服务商 ...

  7. uniapp如何实现多端支付?支付宝微信支付

    今天说一下uniapp实现多端支付,涉及微信公众号,小程序,APP,支付宝APP,支付宝h5支付,多端支付 有疑问可以留言 //点击支付的按钮goPay() {let userId = this.$q ...

  8. 银联支付宝微信共同构筑刷脸支付新生态

    人脸识别手机号作为用户身份验证,银联推出的刷脸付是采用人脸识别支付口令作为支付验证.目前,用户在手机银行或云闪付APP上注册开通并绑定银行卡,可以在全国7个城市的特许商家里使用银联的刷脸支付功能.在店 ...

  9. 【亲测】独家更新CcPay多商户码支付系统,码支付易支付+个人支付宝微信二维码收款app监控+搭建教程

    「BudPay 个人收款」 的原理是通过安装到手机的App监控手机微信.支付宝的二维码扫码支付到账通知并回调开发者应用.消费者在支付的时候是扫描开发者的个人微信.支付宝收款二维码. 支持API调用.手 ...

最新文章

  1. 【Linux】Linux简单操作之vi与vim编辑器
  2. iMeta:德布鲁因图在微生物组研究中的应用(全文翻译,PPT,视频)
  3. php函数剩余时间,php计算剩余时间的自定义函数
  4. sql查询百分之20到百分之40的数据_拼多多面试题:如何查找前20%的数据?
  5. 区块链共识机制分析——论PoW,PoS,DPos和DAG的优缺点
  6. Navicat for MySQL 连接 Mysql 8.0.11 出现1251- Client does not support authentication protocol 错误
  7. MyBatis 多表关联相同字段的解决方案
  8. C++模版 (一) ----- 函数模版
  9. 肺结节目标检测_有肺结节就代表离肺癌不远了?别吓自己,简单几问解答你的困惑...
  10. [转载] 【numpy】numpy.ones()函数
  11. 大学python作业_2020年大学moocPython编程基础作业答案
  12. 【Discuz系列教程2】论坛入口forum.php
  13. JDK与JRE各种版本下载地址
  14. 机器学习——数学基础1,方差平方差标准差均方误差均方根误差
  15. np.sum和np.add.reduce
  16. SaaS销售迎来破局 渠道分销重回主场
  17. android 字体修改颜色代码,Android SearchView 修改字体颜色
  18. Personal Information
  19. 由114.114.114.114和8.8.8.8学习DNS
  20. python没有库怎么办_python缺少依赖(ImportError)库怎么办 | C/C++程序员之家

热门文章

  1. SCOM 常识概念—与其他SC产品集成
  2. 异常:The supplied data appears to be in the Office 2007+ XML
  3. 自动服务器批量装机,PXE高效批量网络装机
  4. data spring 指定时区_今天的工作内容:Spring Boot 2.X整合Spring-cache
  5. 手把手教你如何建立自己的Linux系统
  6. log功能ASP.NET MVC能实现
  7. leetcode前缀树java_Java实现 LeetCode 208 实现 Trie (前缀树)
  8. 给 QtCtreator 工程文件 pro 配置 pthread库和liburcu库
  9. Swagger——与WebAPI整合
  10. html——name与value的使用