当前位置: 首页 > news >正文

《Java接入支付宝沙箱支付全流程详解》

一、引言

二、环境准备

        1. 注册支付宝开放平台账号

        2. 创建沙箱应用

        3. 生成密钥

        4. Natapp内网穿透8080端口

三、Java集成支付宝SDK

        pom.xml

        各种实体类

        AliPay配置类

        服务接口类

四、实现效果

五、结语


一、引言

支付宝沙箱环境为开发者提供了安全的测试环境,本文将详细介绍如何通过Java语言集成支付宝沙箱支付功能,涵盖环境配置、密钥生成、SDK集成及支付流程实现。

在沙箱环境中,开发者可以:

模拟真实的支付场景

测试各种支付结果(成功、失败、退款等)

调试支付回调通知

验证签名机制

使用沙箱环境的主要优势在于可以在不影响真实业务的情况下,充分测试支付系统的各种边界条件和异常情况。

二、环境准备

1. 注册支付宝开放平台账号

支付宝|开放平台 地址:登录 - 支付宝

完成注册与实名认证。

2. 创建沙箱应用

登录后进入控制台,选择「沙箱环境」,系统自动生成应用并获取APPID。

沙箱应用与正式应用功能相同,但所有交易都是模拟的。每个开发者账号默认有一个沙箱应用,无需额外申请。

3. 生成密钥

开启沙箱应用以后,还需要下载支付宝秘钥工具。秘钥工具创建的秘钥,需要填写到查看中。

【沙箱账号】,里面提供了后续在网页上支付时,输入的账号、密码和支付密码。

【沙箱工具】,里面提供了安卓版测试软件,可以在手机扫码支付。

文档中心 | 开放平台 地址:小程序文档 - 支付宝文档中心 - 下载支付宝开放平台秘钥工具 在文档的介绍中,也有很详细的说明

下载生成应用私钥(merchantPrivateKey)和应用公钥。

打开密钥生成工具

选择"生成密钥"→"RSA2(2048位)"

工具会生成应用私钥(merchantPrivateKey)和应用公钥

妥善保存生成的私钥文件(后续代码中需要使用)

上传应用公钥至支付宝开放平台,获取支付宝公钥(alipayPublicKey)。

点击"设置公钥",粘贴上一步生成的应用公钥

保存后,系统会返回支付宝公钥(alipayPublicKey)

记录支付宝公钥,后续验证回调签名时需要

4. Natapp内网穿透8080端口

请参考:《使用Natapp实现内网穿透:轻松打通内外网连接》_natapp怎么样-CSDN博客

Powered By NATAPP       Please visit https://natapp.cn(Ctrl+C to Quit)Tunnel Status           OnlineVersion                 2.4.0Forwarding              http://xxxxxxx.natappfree.cc -> 127.0.0.1:8080Web Interface           DisabledTotal Connections       0

配置要点

隧道协议选择HTTP

本地端口与Spring Boot应用端口一致

免费隧道每24小时更换域名,付费隧道可固定域名

主要关注外部地址:

Forwarding              http://xxxxxxx.natappfree.cc

三、Java集成支付宝SDK

支付配置

app_id:应用ID - 您的APPID,收款账号既是你的APPID对应支付宝账号。

merchant_private_key:商户私钥,【通过支付宝开放平台秘钥工具】创建出来的私钥。公钥填写到网页上,私钥程序里使用。

alipay_public_key:支付宝公钥,在网页上填写公钥后,会给你一个支付宝的公钥。

notify_url:服务器异步通知回调地址,也就是你支付完成后,支付宝调用你的地址。因为我们是在本地做测试,外网是访问不到的。所以为了能做这样的测试,可以回调到我们。那么这里需要使用 natapp做一个内网穿透。

return_url:支付完成后跳转的地址,回调的地址需要公网IP地址或者走内网穿透。

gatewayUrl:支付宝沙箱环境的地址,固定的。

sign_type:签名方式固定的

charset:字符编码固定的

    调用配置

    out_trade_no:你的单号,用你的单号类生成支付单信息。每次创建订单的时候,单号保持唯一。

    total_amount:支付金额

    subject:商品名称

    product_code:固定值;FAST_INSTANT_TRADE_PAY

      pom.xml

      添加支付宝SDK依赖,支付宝SDK封装了与支付宝网关的交互逻辑,包括签名生成、请求发送和响应处理等。

      <!-- 支付宝支付SDK -->
      <!-- 官方文档:https://opendocs.alipay.com/common/02kkv7 -->
      <dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.38.157.ALL</version>
      </dependency>

      各种实体类

      Response:通用响应对象,包含状态码、提示信息和数据体,用于统一接口返回格式。

      Constants:系统常量定义,包括响应码枚举和订单状态枚举,提高代码可读性和可维护性。

      PayOrder:支付订单实体类,记录订单基本信息、状态及支付相关数据。

      PayOrderRes:支付订单响应对象,包含订单ID和支付链接等信息。

      ShopCartReq:购物车请求对象,用于传递用户和商品信息。

      ProductVO:商品值对象,封装商品的基本属性和价格信息。

      Response

      通用响应对象,包含code、info和data字段,用于统一接口返回格式

      import lombok.AllArgsConstructor;
      import lombok.Builder;
      import lombok.Data;
      import lombok.NoArgsConstructor;import java.io.Serializable;/**
      * @Description: 通用响应结果
      */
      @Data
      @Builder
      @NoArgsConstructor
      @AllArgsConstructor
      public class Response<T> implements Serializable {private static final long serialVersionUID = 7000723935764546321L;private String code;private String info;private T data;}
      

      Constants 

      包含系统常量定义,如响应码、订单状态枚举等

      import lombok.AllArgsConstructor;
      import lombok.Getter;
      import lombok.NoArgsConstructor;/*** @description 通用的枚举值*/
      public class Constants {public final static String SPLIT = ",";@AllArgsConstructor@NoArgsConstructor@Getterpublic enum ResponseCode {SUCCESS("0000", "调用成功"),UN_ERROR("0001", "调用失败"),ILLEGAL_PARAMETER("0002", "非法参数"),NO_LOGIN("0003", "未登录"),;private String code;private String info;}@Getter@AllArgsConstructorpublic enum OrderStatusEnum {CREATE("CREATE", "创建完成 - 如果调单了,也会从创建记录重新发起创建支付单"),PAY_WAIT("PAY_WAIT", "等待支付 - 订单创建完成后,创建支付单"),PAY_SUCCESS("PAY_SUCCESS", "支付成功 - 接收到支付回调消息"),DEAL_DONE("DEAL_DONE", "交易完成 - 商品发货完成"),CLOSE("CLOSE", "超时关单 - 超市未支付"),;private final String code;private final String desc;}}
      

      PayOrder 

      支付订单实体,记录订单基本信息、状态和支付信息

      import lombok.AllArgsConstructor;
      import lombok.Builder;
      import lombok.Data;
      import lombok.NoArgsConstructor;import java.math.BigDecimal;
      import java.util.Date;@Data
      @Builder
      @AllArgsConstructor
      @NoArgsConstructor
      public class PayOrder {private Long id; // 主键private String userId; // 用户idprivate String productId; // 商品idprivate String productName; // 商品名称private String orderId; // 订单idprivate Date orderTime; // 下单时间private BigDecimal totalAmount; // 总金额private String status; // 订单状态private String payUrl; // 支付链接private Date payTime; // 支付时间private Date createTime; // 创建时间private Date updateTime; // 修改时间}
      

      PayOrderRes 

      支付订单响应对象,包含订单ID和支付链接

      import lombok.AllArgsConstructor;
      import lombok.Builder;
      import lombok.Data;
      import lombok.NoArgsConstructor;@Data
      @Builder
      @AllArgsConstructor
      @NoArgsConstructor
      public class PayOrderRes {// 用户IDprivate String userId;// 订单IDprivate String orderId;// 支付链接private String payUrl;// 订单状态private Constants.OrderStatusEnum orderStatusEnum;}
      

      ShopCartReq 

      购物车请求对象,包含用户ID和商品ID

      import lombok.AllArgsConstructor;
      import lombok.Builder;
      import lombok.Data;
      import lombok.NoArgsConstructor;@Data
      @Builder
      @AllArgsConstructor
      @NoArgsConstructor
      public class ShopCartReq {// 用户idprivate String userId;// 商品idprivate String productId;}
      

      ProductVO 

      商品值对象,包含商品基本信息

      import lombok.Data;import java.math.BigDecimal;@Data
      @Builder
      @AllArgsConstructor
      @NoArgsConstructor
      public class ProductVO {/** 商品ID */private String productId;/** 商品名称 */private String productName;/** 商品描述 */private String productDesc;/** 商品价格 */private BigDecimal price;}
      

      AliPay配置类

      application.yml

      在配置文件中设置支付宝相关参数,包括应用ID、公私钥、回调地址和网关地址等。

      # ===================== 支付宝支付配置 =====================
      # 沙箱环境文档:https://opendocs.alipay.com/common/02kkv7
      alipay:enabled: true  # 是否启用app_id: # <你的沙箱应用ID>merchant_private_key: # <你的商户私钥>alipay_public_key: # <支付宝公钥>notify_url: http://<可外网访问的域名或内网穿透>/api/v1/alipay/alipay_notify_url  # 异步通知地址return_url: # 同步跳转地址(支付成功页面)gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do  # 沙箱网关地址

      AliPayConfigProperties 

      使用@ConfigurationProperties注解将配置映射到Java类:

      import lombok.Data;
      import org.springframework.boot.context.properties.ConfigurationProperties;@Data
      @ConfigurationProperties(prefix = "alipay", ignoreInvalidFields = true) // 指定配置前缀,忽略无效字段
      public class AliPayConfigProperties {// 「沙箱环境」应用ID - 您的APPID,收款账号既是你的APPID对应支付宝账号。获取地址;https://open.alipay.com/develop/sandbox/appprivate String app_id;// 「沙箱环境」商户私钥,你的PKCS8格式RSA2私钥private String merchant_private_key;// 「沙箱环境」支付宝公钥private String alipay_public_key;// 「沙箱环境」服务器异步通知页面路径private String notify_url;// 「沙箱环境」页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问private String return_url;// 「沙箱环境」private String gatewayUrl;// 签名方式private String sign_type = "RSA2";// 字符编码格式private String charset = "utf-8";// 传输格式private String format = "json";}
      

      AliPayConfig 

      配置支付宝客户端Bean,用于初始化支付宝客户端实例,封装SDK的调用逻辑。

      import com.alipay.api.AlipayClient;
      import com.alipay.api.DefaultAlipayClient;
      import org.springframework.boot.context.properties.EnableConfigurationProperties;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;@Configuration
      @EnableConfigurationProperties(AliPayConfigProperties.class)
      public class AliPayConfig {@Bean("alipayClient")public AlipayClient alipayClient(AliPayConfigProperties properties) {return new DefaultAlipayClient(properties.getGatewayUrl(),properties.getApp_id(),properties.getMerchant_private_key(),properties.getFormat(),properties.getCharset(),properties.getAlipay_public_key(),properties.getSign_type());}}
      

      服务接口类

      AliPayController 

      提供创建支付订单和处理支付宝回调的接口,包括订单生成、签名验证和状态更新等功能。

      import com.alipay.api.AlipayApiException;
      import com.alipay.api.internal.util.AlipaySignature;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
      import javax.servlet.http.HttpServletRequest;
      import java.util.HashMap;
      import java.util.Map;@Slf4j
      @RestController()
      @CrossOrigin("*")
      @RequestMapping("/api/v1/alipay/")
      public class AliPayController {@Value("${alipay.alipay_public_key}")private String alipayPublicKey;@Resourceprivate IOrderService orderService;/*** http://localhost:8080/api/v1/alipay/create_pay_order* 创建支付单接口,返回支付链接url* {* "userId": "10001", // 用户ID【实际产生中会通过登录模块获取,不需要透彻,这里只是方便】* "productId": "100001"* }*/@RequestMapping(value = "create_pay_order", method = RequestMethod.POST)public Response<String> createPayOrder(@RequestBody CreatePayRequestDTO createPayRequestDTO) {try {log.info("商品下单,根据商品ID创建支付单开始 userId:{} productId:{}", createPayRequestDTO.getUserId(), createPayRequestDTO.getUserId());String userId = createPayRequestDTO.getUserId();String productId = createPayRequestDTO.getProductId();// 购物车商品对象ShopCartReq shopCartReq = ShopCartReq.builder().userId(userId).productId(productId).build();// 下单从,创建支付单PayOrderRes payOrderRes = orderService.createOrder(shopCartReq);log.info("商品下单,根据商品ID创建支付单完成 userId:{} productId:{} orderId:{}", userId, productId, payOrderRes.getOrderId());return Response.<String>builder().code(Constants.ResponseCode.SUCCESS.getCode()).info(Constants.ResponseCode.SUCCESS.getInfo()).data(payOrderRes.getPayUrl()) // 返回支付链接.build();} catch (Exception e) {log.error("商品下单,根据商品ID创建支付单失败 userId:{} productId:{}", createPayRequestDTO.getUserId(), createPayRequestDTO.getUserId(), e);return Response.<String>builder().code(Constants.ResponseCode.UN_ERROR.getCode()).info(Constants.ResponseCode.UN_ERROR.getInfo()).build();}}/*** http://xxxx.natapp1.cc/api/v1/alipay/alipay_notify_url* 支付宝支付结果异步通知回调接口** @param request HTTP请求对象,包含支付宝回调参数* @return 处理结果:"success"表示处理成功,"false"表示处理失败* @throws AlipayApiException 支付宝API异常*/@RequestMapping(value = "alipay_notify_url", method = RequestMethod.POST)public String payNotify(HttpServletRequest request) throws AlipayApiException {try {// 1. 打印回调日志(建议记录原始回调参数,方便排查问题)log.info("支付回调,消息接收 {}", request.getParameter("trade_status"));// 2. 校验交易状态(只处理支付成功的回调)if (!"TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {log.warn("非成功交易状态,忽略处理. 状态: {}", request.getParameter("trade_status"));return "false";}// 3. 转换请求参数格式(Map<String,String[]> -> Map<String,String>)Map<String, String> params = new HashMap<>();Map<String, String[]> requestParams = request.getParameterMap();for (String name : requestParams.keySet()) {params.put(name, request.getParameter(name)); // 只取第一个值}// 4. 获取关键业务参数String tradeNo = params.get("out_trade_no");      // 商户订单号String gmtPayment = params.get("gmt_payment");    // 支付时间String alipayTradeNo = params.get("trade_no");    // 支付宝交易号// 5. 支付宝签名验证校验(重要安全措施)String sign = params.get("sign");String content = AlipaySignature.getSignCheckContentV1(params);boolean checkSignature = AlipaySignature.rsa256CheckContent(content,sign,alipayPublicKey,"UTF-8");if (!checkSignature) {log.error("支付宝签名验证失败,疑似非法请求. 订单号: {}", tradeNo);return "false";}// 6. 验签通过后记录回调详情(建议持久化存储)log.info("支付回调详情 => 交易名称: {}", params.get("subject"));log.info("支付回调详情 => 交易状态: {}", params.get("trade_status"));log.info("支付回调详情 => 支付宝交易号: {}", alipayTradeNo);log.info("支付回调详情 => 商户订单号: {}", tradeNo);log.info("支付回调详情 => 交易金额: {}", params.get("total_amount"));log.info("支付回调详情 => 买家ID: {}", params.get("buyer_id"));log.info("支付回调详情 => 付款时间: {}", gmtPayment);log.info("支付回调详情 => 实付金额: {}", params.get("buyer_pay_amount"));// 7. 更新订单状态(建议增加幂等处理)log.info("支付回调,开始更新订单状态 {}", tradeNo);orderService.changeOrderPaySuccess(tradeNo);// 8. 返回成功响应(必须返回"success"字符串)return "success";} catch (Exception e) {log.error("支付回调,处理失败", e);return "false";}}}
      

      IOrderService 

      定义订单服务的接口方法,包括创建订单和更新订单状态等。

      import java.util.List;/*** @description 订单服务接口*/
      public interface IOrderService {/*** 创建订单* @param shopCartReq* @return*/PayOrderRes createOrder(ShopCartReq shopCartReq) throws Exception;/*** 修改订单支付成功* @param orderId*/void changeOrderPaySuccess(String orderId);
      }
      

      OrderServiceImpl 

      实现订单服务的具体逻辑,包括订单查询、支付单创建和状态更新等,确保支付流程的完整性和可靠性。

      import com.alibaba.fastjson.JSON;
      import com.alibaba.fastjson.JSONObject;
      import com.alipay.api.AlipayApiException;
      import com.alipay.api.AlipayClient;
      import com.alipay.api.request.AlipayTradePagePayRequest;
      import com.google.common.eventbus.EventBus;
      import lombok.extern.slf4j.Slf4j;
      import org.apache.commons.lang3.RandomStringUtils;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Service;import javax.annotation.Resource;
      import java.math.BigDecimal;
      import java.util.Date;
      import java.util.List;/*** @description 订单服务*/
      @Slf4j
      @Service
      public class OrderServiceImpl implements IOrderService {@Value("${alipay.notify_url}")private String notifyUrl;@Value("${alipay.return_url}")private String returnUrl;@Resourceprivate AlipayClient alipayClient; // 支付宝客户端@Overridepublic PayOrderRes createOrder(ShopCartReq shopCartReq) throws Exception {// 1. 查询当前用户是否存在未支付订单或掉单订单PayOrder payOrderReq = new PayOrder();payOrderReq.setUserId(shopCartReq.getUserId());payOrderReq.setProductId(shopCartReq.getProductId());//PayOrder unpaidOrder = orderDao.queryUnPayOrder(payOrderReq); // 数据库中进行查询if (null != unpaidOrder && Constants.OrderStatusEnum.PAY_WAIT.getCode().equals(unpaidOrder.getStatus())) {log.info("创建订单-存在,已存在未支付订单。userId:{} productId:{} orderId:{}", shopCartReq.getUserId(), shopCartReq.getProductId(), unpaidOrder.getOrderId());return PayOrderRes.builder().orderId(unpaidOrder.getOrderId()).payUrl(unpaidOrder.getPayUrl()).build();} else if (null != unpaidOrder && Constants.OrderStatusEnum.CREATE.getCode().equals(unpaidOrder.getStatus())) {// 网络等其他问题,导致订单状态未更新成等待支付,则重新创建支付单log.info("创建订单-存在,存在未创建支付单订单,创建支付单开始 userId:{} productId:{} orderId:{}", shopCartReq.getUserId(), shopCartReq.getProductId(), unpaidOrder.getOrderId());PayOrder payOrder = doPrepayOrder(unpaidOrder.getProductId(), unpaidOrder.getProductName(), unpaidOrder.getOrderId(), unpaidOrder.getTotalAmount());return PayOrderRes.builder().orderId(payOrder.getOrderId()).payUrl(payOrder.getPayUrl()).build();} else {log.info("创建订单-不存在,存在未创建支付单订单,创建支付单开始 userId:{} productId:{}", shopCartReq.getUserId(), shopCartReq.getProductId());}// 2. 查询商品 & 创建订单ProductVO productVO = new ProductVO();productVO.setProductId(productId);productVO.setProductName("测试商品");productVO.setProductDesc("这是一个测试商品");productVO.setPrice(new BigDecimal("13.14"));String orderId = RandomStringUtils.randomNumeric(16); // 生成16位随机订单号(正式环境建议使用分布式ID生成器(如雪花算法)代替)orderDao.insert(PayOrder.builder().userId(shopCartReq.getUserId()).productId(shopCartReq.getProductId()).productName(productVO.getProductName()).orderId(orderId).totalAmount(productVO.getPrice()).orderTime(new Date()).status(Constants.OrderStatusEnum.CREATE.getCode()).build());// 3. 创建支付单PayOrder payOrder = doPrepayOrder(productVO.getProductId(), productVO.getProductName(), orderId, productVO.getPrice());return PayOrderRes.builder().orderId(orderId).payUrl(payOrder.getPayUrl()).build();}@Overridepublic void changeOrderPaySuccess(String orderId) {// 检查此订单是否已支付过PayOrder payOrder = orderDao.queryByOrderIdAndStatus(orderId, Constants.OrderStatusEnum.PAY_WAIT.getCode());if (payOrder == null) return;// 更新支付单为支付成功PayOrder updatePayOrder = new PayOrder();updatePayOrder.setOrderId(orderId);updatePayOrder.setStatus(Constants.OrderStatusEnum.PAY_SUCCESS.getCode());orderDao.changeOrderPaySuccess(updatePayOrder);// 消息队列发送支付成功消息......}/*** 创建支付宝预支付订单** @param productId 商品ID* @param productName 商品名称(将作为支付显示的标题)* @param orderId 商户订单号(唯一标识)* @param totalAmount 订单总金额(单位:元)* @return PayOrder 支付订单信息* @throws AlipayApiException 支付宝API调用异常*/private PayOrder doPrepayOrder(String productId, String productName, String orderId, BigDecimal totalAmount)throws AlipayApiException {// 1. 创建支付宝页面支付请求对象AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();// 设置异步通知回调地址(支付成功后支付宝服务器主动通知的地址),用于支付宝服务器在支付成功后主动通知商户服务器,触发订单状态更新等业务逻辑request.setNotifyUrl(notifyUrl);// 设置同步跳转地址(支付成功后用户浏览器跳转的地址),支付成功后,支付宝通过浏览器重定向跳转到该地址,用于向用户展示支付结果,需要公网IP地址或者走内网穿透request.setReturnUrl(returnUrl);// 2. 构建业务请求参数JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", orderId);      // 商户订单号bizContent.put("total_amount", totalAmount.toString()); // 订单金额(字符串格式)bizContent.put("subject", productName);       // 订单标题/商品名称bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 销售产品码(固定值)// 将业务参数设置到请求中request.setBizContent(bizContent.toString());// 3. 调用支付宝接口生成支付表单String form = alipayClient.pageExecute(request).getBody();// 4. 构建支付订单信息PayOrder payOrder = new PayOrder();payOrder.setOrderId(orderId);                 // 设置订单IDpayOrder.setPayUrl(form);                     // 设置支付宝返回的表单HTMLpayOrder.setStatus(Constants.OrderStatusEnum.PAY_WAIT.getCode()); // 设置订单状态为"等待支付"// 5. 更新订单支付信息到数据库//orderDao.updateOrderPayInfo(payOrder);return payOrder;}}
      

      四、实现效果

      通过调用接口生成支付链接,将链接粘贴至HTML文件并在浏览器中打开,即可跳转至支付宝沙箱支付页面。使用沙箱提供的买家账号完成支付操作后,系统会异步通知本地服务并更新订单状态,实现完整的支付流程测试。

      Apifox调用接口得到支付链接

      将它负责粘贴到html文件,删除不必要的\与\n,并且打开到浏览器

      根据平台的买家账号进行购买即可实现支付订单。

      五、结语

      通过本文的详细指导,您已经完成了从零开始集成支付宝沙箱支付功能的完整流程。让我们回顾一下关键要点:

      安全测试环境:支付宝沙箱环境为开发者提供了零风险的测试平台,让您可以在不影响真实业务的情况下全面验证支付流程。

      全流程覆盖:从账号注册、密钥配置到SDK集成和回调处理,本文提供了端到端的解决方案,确保每个环节都有据可依。

      希望本指南能帮助您顺利实现支付宝支付功能的集成。如果在实施过程中遇到任何问题,建议:

      查阅支付宝官方文档

      检查应用日志获取详细错误信息

      在开发者社区寻求帮助

      本文详细介绍了Java接入支付宝沙箱支付的全流程,从环境准备到代码实现,逐步引导开发者完成支付功能的集成。支付宝沙箱环境为开发者提供了安全、便捷的测试平台,帮助其在真实业务上线前充分验证系统功能。希望通过本文的指导,开发者能够顺利完成支付功能的接入,为项目的正式上线奠定坚实基础。

      如果对此篇文章有什么疑问或者建议欢迎评论区留言讨论!


      文章转载自:

      http://U4e8UEnu.bmfqg.cn
      http://g3G1lUtx.bmfqg.cn
      http://7FlRtecn.bmfqg.cn
      http://mDeLRak9.bmfqg.cn
      http://WN4ArcgC.bmfqg.cn
      http://q5J5uSHg.bmfqg.cn
      http://l50moKBJ.bmfqg.cn
      http://tgweszeE.bmfqg.cn
      http://QVmOqUxf.bmfqg.cn
      http://wbT9LsFw.bmfqg.cn
      http://5Ri4uk8Y.bmfqg.cn
      http://GXT4KhQh.bmfqg.cn
      http://MWWRuWXL.bmfqg.cn
      http://RsJRm22X.bmfqg.cn
      http://amhE0NCu.bmfqg.cn
      http://eknGWiVT.bmfqg.cn
      http://UCefzRXE.bmfqg.cn
      http://luZLae01.bmfqg.cn
      http://tA4P14DN.bmfqg.cn
      http://3nJ7DM90.bmfqg.cn
      http://Xwubtzwq.bmfqg.cn
      http://Wu7RJEch.bmfqg.cn
      http://aDjdGaHD.bmfqg.cn
      http://CxO6h1OS.bmfqg.cn
      http://pQbAUGT6.bmfqg.cn
      http://RvL2NkJi.bmfqg.cn
      http://bBL7pv86.bmfqg.cn
      http://4fWAXIBE.bmfqg.cn
      http://mGOwZVOg.bmfqg.cn
      http://xa8fFR5T.bmfqg.cn
      http://www.dtcms.com/a/386292.html

      相关文章:

    • DevOps实战(8) - 使用Arbess+GitLab+PostIn实现Go项目自动化部署
    • 趣味学RUST基础篇(高级特征)
    • 随机森林(Random Forest)学习笔记
    • css之Flex响应式多列布局,根据容器宽度自动调整显示2列或3列布局,支持多行排列
    • HTML应用指南:利用POST请求获取全国中石化易捷门店位置信息
    • PDF24 Creator:免费全能的PDF处理工具
    • 小程序交互与一些技术总结
    • Spring Cloud - 面试知识点(负载均衡)
    • 易特ERP软件局域网版安装教程
    • qt QBoxSet详解
    • 电脑散热风扇有噪音怎么解决
    • 行业分享丨汽车电磁兼容仿真技术与应用
    • 缓存与数据库一致性的4大坑及终极解决方案
    • 机器学习面试题:请讲一讲分类评估方式?
    • 【pure-admin】前端使用pure-admin后台管理系统框架,后端使用FastAPI的前端向后端加密发送用户登录密码的完整示例
    • 从 Node.js 安装到 Vue 3 开发环境搭建
    • Python单元测试框架之pytest -- 生成测试报告
    • 使用HBuilderX新建uniapp项目
    • 医疗行业安全合规数据管理平台:构建高效协作与集中化知识沉淀的一体化解决方案
    • 从一次鼠标点击窥探操作系统内核:中断、驱动、IPC与内存安全的奇幻之旅
    • 【超详细】C#的单例模式
    • 加快 NoETL 数据工程实践, Aloudata 荣登《2025 中国数智化转型升级创新服务企业》榜单
    • 香港服务器CN2带宽价格多少钱?很贵吗?
    • 180 课时吃透 Go 语言游戏后端系列1:第一个Go程序
    • MSI 与 IOAPIC LAPIC 如何协作,操作系统如何初始化和使用他们
    • 数据库优化(六)安全字段脱敏设计—东方仙盟金丹期
    • java21学习笔记
    • 大厂综合题库解析
    • 算法奇妙屋(2)-模拟
    • 贪心算法应用:区间调度问题详解