Android 一行代码解决支付宝、微信、银联支付

2024-01-24 01:48

本文主要是介绍Android 一行代码解决支付宝、微信、银联支付,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在Android 中只要提到支付,就必然会使用支付宝、微信、银联这三大支付渠道,所以只要遇到支付需求,就必须去跟着三大支付渠道的文档去对接,每次都是体力活,能不能把三大支付渠写成统一的支付模块,只需要对支付所需要的信息进行配置,一句方法调用即可完成支付?

这篇博客就是完成这个需求的,下面让我来详细说明实现步骤。

准备

  1. 请务必到支付宝、银联、微信,下载好Android所需要的SDK备用。
  2. 支付宝Sdk 使用的是蚂蚁金服下的2.0版本。
  3. 银联支付,请使用2016年12月后发布的版本,因为该版本已经将插件支付和内置支付合并在一起了。不需要检测是否安装插件。

支付所需数据

支付宝

字段说明
orderInfo支付宝2.0SDK中在服务器端生成好的订单信息

参考网址:

https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.R90GnU&treeId=59&articleId=103663&docType=1

使用建造者模式,创建支付宝支付所需数据

public class AliPayConfig {private String orderInfo;private Activity context;private AliPayConfig() {}public String getOrderInfo() {return orderInfo;}public Activity getContext() {return context;}public static class Builder {private String orderInfo;private Activity context;public Builder() {super();}public AliPayConfig.Builder with(Activity context) {this.context = context;return this;}/*** 设置支付宝支付OrderInfo** @param orderInfo* @return*/public AliPayConfig.Builder setOrderInfo(String orderInfo) {this.orderInfo = orderInfo;return this;}public AliPayConfig build() {AliPayConfig aliPayPayConfig = new AliPayConfig();aliPayPayConfig.context = this.context;aliPayPayConfig.orderInfo = this.orderInfo;return aliPayPayConfig;}}
}

微信

字段说明
appId微信支付AppID
partnerId支付商户号
prepayId预支付码(重要)
packageValuepackageValue
nonceStrnonceStr
timeStamp时间戳
sign签名

参考网址:

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2

使用建造者模式创建微信支付所需数据

public class WeiXinPayConfig {private Activity context;private String appId;private String partnerId;private String prepayId;private String packageValue;private String nonceStr;private String timeStamp;private String sign;private WeiXinPayConfig() {}public Activity getContext() {return context;}public String getAppId() {return appId;}public String getPartnerId() {return partnerId;}public String getPrepayId() {return prepayId;}public String getPackageValue() {return packageValue;}public String getNonceStr() {return nonceStr;}public String getTimeStamp() {return timeStamp;}public String getSign() {return sign;}public static class Builder {private Activity context;//微信支付AppIDprivate String appId;//微信支付商户号private String partnerId;//预支付码(重要)private String prepayId;//"Sign=WXPay"private String packageValue = "Sign=WXPay";private String nonceStr;//时间戳private String timeStamp;//签名private String sign;public Builder() {super();}public Builder with(Activity context) {this.context = context;return this;}/*** 设置微信支付AppID** @param appId* @return*/public Builder setAppId(String appId) {this.appId = appId;return this;}/*** 微信支付商户号** @param partnerId* @return*/public Builder setPartnerId(String partnerId) {this.partnerId = partnerId;return this;}/*** 设置预支付码(重要)** @param prepayId* @return*/public Builder setPrepayId(String prepayId) {this.prepayId = prepayId;return this;}/*** 设置** @param packageValue* @return*/public Builder setPackageValue(String packageValue) {this.packageValue = packageValue;return this;}/*** 设置** @param nonceStr* @return*/public Builder setNonceStr(String nonceStr) {this.nonceStr = nonceStr;return this;}/*** 设置时间戳** @param timeStamp* @return*/public Builder setTimeStamp(String timeStamp) {this.timeStamp = timeStamp;return this;}/*** 设置签名** @param sign* @return*/public Builder setSign(String sign) {this.sign = sign;return this;}public WeiXinPayConfig build() {WeiXinPayConfig weiXinPayConfig = new WeiXinPayConfig();weiXinPayConfig.context = this.context;//微信支付AppIDweiXinPayConfig.appId = this.appId;//微信支付商户号weiXinPayConfig.partnerId = this.partnerId;//预支付码(重要)weiXinPayConfig.prepayId = this.prepayId;//"Sign=WXPay"weiXinPayConfig.packageValue = this.packageValue;weiXinPayConfig.nonceStr = this.nonceStr;//时间戳weiXinPayConfig.timeStamp = this.timeStamp;//签名weiXinPayConfig.sign = this.sign;return weiXinPayConfig;}}
}

银联

字段说明
tradeCode文档中描述的Tn
serverModel文档中描述的serverModel

参考网址:

https://open.unionpay.com/ajweb/help/file/techFile?productId=3

手机控件支付开发包(Android 版/app开发包/控件使用指南/中国银联手机支付控件接入指南Android.doc

使用建造者模式创建银联所需数据

public class UnionBankPayConfig {private Activity context;private String tradeCode;private String serverModel;private UnionBankPayConfig() {}public Activity getContext() {return context;}public String getTradeCode() {return tradeCode;}public String getServerModel() {return serverModel;}public static class Builder {private Activity context;private String tradeCode;private String serverModel;public Builder() {super();}public UnionBankPayConfig.Builder with(Activity context) {this.context = context;return this;}/*** 设置银联支付Tn** @param tradeCode* @return*/public UnionBankPayConfig.Builder setTradeCode(String tradeCode) {this.tradeCode = tradeCode;return this;}/*** 设置银联支付服务模式** @param serverModel “00” – 银联正式环境 ,“01” – 银联测试环境,该环境中不发生真实交易* @return*/public UnionBankPayConfig.Builder setServerModel(String serverModel) {this.serverModel = serverModel;return this;}public UnionBankPayConfig build() {UnionBankPayConfig unionBankPayConfig = new UnionBankPayConfig();unionBankPayConfig.context = this.context;unionBankPayConfig.tradeCode = this.tradeCode;unionBankPayConfig.serverModel = this.serverModel;return unionBankPayConfig;}}
}

抽象PayFunction

根据阅读三家支付渠道文档,发现,其实大致步骤可以归结为两步。

  1. 检查是否安装有支付渠道插件
  2. 支付,获取同步返回信息

提取共性,创建PayFunction接口

public interface PayFunction {void payOrder();void checkPayState(CheckStateListener checkStateListener);
}

支付宝


import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.widget.Toast;import com.alipay.sdk.app.PayTask;
import com.ta.utdid2.android.utils.StringUtils;import org.unreal.common.pay.CheckStateListener;
import org.unreal.common.pay.PayFunction;
import org.unreal.common.pay.PayResultListener;import java.util.Map;public class AliPay implements PayFunction {private static final int SDK_PAY_FLAG = 1;private static final int SDK_CHECK_FLAG = 2;private AliPayConfig config;private PayResultListener listener;private Handler mHandler;private CheckStateListener checkStateListener;public AliPay(PayResultListener listener) {this.listener = listener;}@Overridepublic void payOrder() {Runnable checkRunnable = new Runnable() {@Overridepublic void run() {// 构造PayTask 对象PayTask payTask = new PayTask(config.getContext());// 调用查询接口,获取查询结果Map<String, String> result = payTask.payV2(config.getOrderInfo(), true);Message msg = new Message();msg.what = SDK_PAY_FLAG;msg.obj = result;mHandler.sendMessage(msg);}};Thread payThread = new Thread(checkRunnable);payThread.start();}@Overridepublic void checkPayState(CheckStateListener checkStateListener) {this.checkStateListener = checkStateListener;Runnable checkRunnable = new Runnable() {@Overridepublic void run() {// 构造PayTask 对象PayTask payTask = new PayTask(config.getContext());// 调用查询接口,获取查询结果String result = payTask.getVersion();Message msg = new Message();msg.what = SDK_CHECK_FLAG;msg.obj = result;mHandler.sendMessage(msg);}};Thread checkThread = new Thread(checkRunnable);checkThread.start();}public AliPay setConfig(final AliPayConfig config) {this.config = config;// 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
//                        String resultInfo = payResult.getResult();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
// 判断resultStatus 为非“9000”则代表可能支付失败
// “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case SDK_PAY_FLAG: {PayResult payResult = new PayResult((Map<String, String>) msg.obj);// 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
//                        String resultInfo = payResult.getResult();String resultStatus = payResult.getResultStatus();// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档if (TextUtils.equals(resultStatus, "9000")) {Toast.makeText(config.getContext(), "支付宝支付成功", Toast.LENGTH_SHORT).show();if (listener != null) listener.onPaySuccess();} else {// 判断resultStatus 为非“9000”则代表可能支付失败// “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)if (TextUtils.equals(resultStatus, "8000")) {Toast.makeText(config.getContext(), "支付宝支付结果确认中", Toast.LENGTH_SHORT).show();if (listener != null) listener.onPayConfirming();} else {// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误Toast.makeText(config.getContext(), "支付宝支付失败", Toast.LENGTH_SHORT).show();if (listener != null) listener.onPayFailure();}}break;}case SDK_CHECK_FLAG: {if (listener != null) {if (StringUtils.isEmpty(msg.obj.toString())) {Toast.makeText(config.getContext(), "没有安装支付宝或支付宝版本过低,无法使用支付宝支付!", Toast.LENGTH_SHORT).show();checkStateListener.checkState(false);} else {checkStateListener.checkState(true);}}break;}default:break;}}};return this;}
}

这种实现方案有漏洞,没有使用公钥验证返回值是否合法,有风险。


import android.text.TextUtils;import java.util.Map;public class PayResult {private String resultStatus;private String result;private String memo;public PayResult(Map<String, String> rawResult) {if (rawResult == null) {return;}for (String key : rawResult.keySet()) {if (TextUtils.equals(key, "resultStatus")) {resultStatus = rawResult.get(key);} else if (TextUtils.equals(key, "result")) {result = rawResult.get(key);} else if (TextUtils.equals(key, "memo")) {memo = rawResult.get(key);}}}@Overridepublic String toString() {return "resultStatus={" + resultStatus + "};memo={" + memo+ "};result={" + result + "}";}/*** @return the resultStatus*/public String getResultStatus() {return resultStatus;}/*** @return the memo*/public String getMemo() {return memo;}/*** @return the result*/public String getResult() {return result;}
}

微信

package com.drawthink.pay.weixin;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.widget.Toast;import com.drawthink.pay.PayModule;
import com.drawthink.pay.PayResultListener;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;public class WeiXinPay implements PayModule {//微信支付核心apiprivate IWXAPI mWXApi;private PayResultListener listener;private WeiXinPayConfig weiXinPayConfig;private BroadcastReceiver receiver;public WeiXinPay(WeiXinPayConfig weiXinPayConfig) {this.weiXinPayConfig = weiXinPayConfig;mWXApi = WXAPIFactory.createWXAPI(weiXinPayConfig.getContext(), null);mWXApi.registerApp(weiXinPayConfig.getAppId());onEvent();}@Overridepublic PayModule setOnPayResultListener(PayResultListener listener) {this.listener = listener;return this;}@Overridepublic void payOrder() {PayReq request = new PayReq();request.appId = weiXinPayConfig.getAppId();request.partnerId = weiXinPayConfig.getPartnerId();request.prepayId = weiXinPayConfig.getPrepayId();request.packageValue =weiXinPayConfig.getPackageValue() != null? weiXinPayConfig.getPackageValue() : "Sign=WXPay";request.nonceStr = weiXinPayConfig.getNonceStr();request.timeStamp = weiXinPayConfig.getTimeStamp();request.sign = weiXinPayConfig.getSign();request.signType = weiXinPayConfig.getSignType();mWXApi.sendReq(request);}@Overridepublic void checkPayState() {if(listener != null){if(!mWXApi.isWXAppInstalled()){Toast.makeText(weiXinPayConfig.getContext(), "没有安装微信,无法使用微信支付!", Toast.LENGTH_SHORT).show();}if(!mWXApi.isWXAppSupportAPI()){Toast.makeText(weiXinPayConfig.getContext(), "当前微信版本过低,无法使用微信支付,请升级微信!", Toast.LENGTH_SHORT).show();}listener.onPayCheck(mWXApi.isWXAppInstalled() && mWXApi.isWXAppSupportAPI());}}
//重要!!!因微信的支付结果回调在yourpackagename.wxapi.WXPayEntryActivity.java中,为了统一处理,所以就在WXPayEntryActivity 中通过本地广播发了一个通知,来处理回调private void onEvent() {
//        0 成功  展示成功页面
//        -1    错误  可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
//        -2    用户取消    无需处理。发生场景:用户不支付了,点击取消,返回APP。IntentFilter filter = new IntentFilter("org.unreal.pay.weiXinPayResult");//        0 成功  展示成功页面
//  -1  错误       -2 用户取消receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {int errCode = intent.getIntExtra("errCode", -1);if (errCode == BaseResp.ErrCode.ERR_OK) { //        0 成功    展示成功页面WeiXinPay.this.listener.onPaySuccess();} else {//  -1  错误       -2 用户取消WeiXinPay.this.listener.onPayFailure();}LocalBroadcastManager.getInstance(weiXinPayConfig.getContext()).unregisterReceiver(receiver);}};LocalBroadcastManager.getInstance(weiXinPayConfig.getContext()).registerReceiver(receiver,filter);}
}

yourpackagename.wxapi.WXPayEntryActivity.java

package com.drawthink.hospital.wxapi;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.SyncStateContract;
import android.support.v4.content.LocalBroadcastManager;import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;public class WXPayEntryActivity  extends Activity implements IWXAPIEventHandler {private IWXAPI api;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);api = WXAPIFactory.createWXAPI(this, null);api.handleIntent(getIntent(), this);}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);setIntent(intent);api.handleIntent(intent, this);}@Overridepublic void onReq(BaseReq req) {}@Overridepublic void onResp(BaseResp resp) {/*** 微信支付成功回调会开启一个activity,并执行onResp方法,我不希望出现这个界面,所以finish了,在这之前,我发送一个广播* 在广播中我做了回调后的操作**/if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {//发送广播,为intent添加的String必须一致,接收广播处LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("org.unreal.pay.weiXinPayResult").putExtra("errCode", resp.errCode));}finish();}
}

银联


import android.content.Intent;
import android.widget.Toast;import com.unionpay.UPPayAssistEx;import org.unreal.common.pay.CheckStateListener;
import org.unreal.common.pay.PayFunction;
import org.unreal.common.pay.PayResultListener;public class UnionBankPay implements PayFunction {private PayResultListener listener;private UnionBankPayConfig config;public UnionBankPay(PayResultListener listener) {this.listener = listener;}@Overridepublic void payOrder() {UPPayAssistEx.startPay(config.getContext(), null, null, config.getTradeCode(), config.getServerModel());}@Overridepublic void checkPayState(CheckStateListener checkStateListener) {checkStateListener.checkState(true);}public void processPayResponse(Intent data) {if (data == null) {return;}String msg = "";/** 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消*/String str = data.getExtras().getString("pay_result");if ("success".equalsIgnoreCase(str)) {// 17-3-3 此处任务只要返回Success 即认为支付成功,此处逻辑会有风险// 如果想对结果数据验签,可使用下面这段代码,但建议不验签,直接去商户后台查询交易结果// 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) {
                }
//            }// 结果result_data为成功时,去商户后台查询一下再展示成功Toast.makeText(config.getContext(), "银联支付成功", Toast.LENGTH_SHORT).show();if (listener != null) {listener.onPaySuccess();}} else if ("fail".equalsIgnoreCase(str)) {Toast.makeText(config.getContext(), "银联支付失败", Toast.LENGTH_SHORT).show();if (listener != null) {listener.onPayFailure();}} else if ("cancel".equalsIgnoreCase(str)) {if (listener != null) {Toast.makeText(config.getContext(), "银联支付失败,用户取消了支付", Toast.LENGTH_SHORT).show();listener.onPaySuccess();}}}public UnionBankPay setConfig(UnionBankPayConfig config) {this.config = config;return this;}
}

此代码也没有进行远程验证,仅通过支付控件返回字符串判断支付结果,有风险!

检查是否安装支付渠道插件回调接口

主要用于检查插件是否安装,抹除掉同步、异步检查的差别,统一采用回调接口方式来返回检查结果


public interface CheckStateListener {//true 表示 控件安装 false 表示 控件版本过低 或 控件未安装void checkState(boolean state);
}

支付结果回调接口

主要用于支付结果的获取,支付宝提供了三个支付结果,银联、微信提供了两个支付结果。接口设计取了支付宝接口的三个状态,包含了微信、银联支付结果。

public interface PayResultListener {//支付成功void onPaySuccess();//支付失败(包含取消支付)void onPayFailure();//支付结果等待确认中(仅支付宝提供该状态)void onPayConfirming();
}

PayFacade 类,支付调用入口


import android.content.Intent;import org.unreal.common.pay.impl.alipay.AliPay;
import org.unreal.common.pay.impl.alipay.AliPayConfig;
import org.unreal.common.pay.impl.unionbank.UnionBankPay;
import org.unreal.common.pay.impl.unionbank.UnionBankPayConfig;
import org.unreal.common.pay.impl.weixin.WeiXinPay;
import org.unreal.common.pay.impl.weixin.WeiXinPayConfig;public class PayFacade {private static UnionBankPay unionBankPay;private static WeiXinPay weiXinPay;private static AliPay aliPay;boolean unionBank = false;public PayFacade(PayResultListener listener){if(aliPay == null) {aliPay = new AliPay(listener);}if(weiXinPay == null) {weiXinPay = new WeiXinPay(listener);}if(unionBankPay == null) {unionBankPay = new UnionBankPay(listener);}}public boolean isUnionBank() {return unionBank;}public void unionProcessResult(Intent intent){unionBankPay.processPayResponse(intent);}public void pay(final AliPayConfig aliPayConfig) {aliPay.setConfig(aliPayConfig);pay(aliPay);unionBank = false;}public void pay(WeiXinPayConfig weiXinPayConfig){weiXinPay.setConfig(weiXinPayConfig);pay(weiXinPay);unionBank = false;}public void pay(UnionBankPayConfig unionBankPayConfig){unionBankPay.setConfig(unionBankPayConfig);pay(unionBankPay);unionBank = true;}private void pay(final PayFunction payModule){payModule.checkPayState(new CheckStateListener(){@Overridepublic void checkState(boolean state) {if(state){payModule.payOrder();}}});}
}

因为银联的回调需要在onActivityForResult方法中执行,为了调用者不许关心处理过程,特意封装了isUnionBank方法,来进一步处理银联回调。

使用


import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;import org.unreal.common.application.R;
import org.unreal.common.pay.PayFacade;
import org.unreal.common.pay.PayResultListener;
import org.unreal.common.pay.impl.alipay.AliPayConfig;
import org.unreal.common.pay.impl.unionbank.UnionBankPayConfig;
import org.unreal.common.pay.impl.weixin.WeiXinPayConfig;import butterknife.ButterKnife;
import butterknife.OnClick;public class MainActivity extends AppCompatActivity {private PayFacade facade;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);initPayFacade();}private void initPayFacade() {facade = new PayFacade(new PayResultListener(){@Overridepublic void onPaySuccess() {}@Overridepublic void onPayFailure() {}@Overridepublic void onPayConfirming() {}});}@OnClick({R.id.button2, R.id.button3, R.id.button4})public void onClick(View view) {switch (view.getId()) {case R.id.button2://支付宝支付(测试参数,请配合实际场景,从服务器取到后,装配到pay方法中使用)//facade.pay(new AliPayConfig.Builder().with(this).build());break;case R.id.button3://微信支付(测试参数,请配合实际场景,从服务器取到后,装配到pay方法中使用)//facade.pay(new WeiXinPayConfig.Builder().with(this).build());break;case R.id.button4://银联支付(测试参数,请配合实际场景,从服务器取到后,装配到pay方法中使用)//facade.pay(new UnionBankPayConfig.Builder().with(this).build());break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {//银联需要在onActivityResult处理支付结果,为了简化调用者处理,此处判断是否使用银联支付,如果使用银联支付,则将data 传递给封装好的处理方法来处理if(facade.isUnionBank()){facade.unionProcessResult(data);}super.onActivityResult(requestCode, resultCode, data);}
}

代码地址

https://github.com/ChineseLincoln/Dagger2Mvp/tree/v3

v3 分之下,pay library项目

这篇关于Android 一行代码解决支付宝、微信、银联支付的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/638191

相关文章

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.