热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java对接支付宝的支付、退款、提现

本篇主要是正对Java对接支付宝的常用功能,需要开通个人的沙箱环境和内网穿透(我用了阿里云服务器)。集成前提:开发者在集成和开发前需要了

本篇主要是正对Java对接支付宝的常用功能,需要开通个人的沙箱环境和内网穿透(我用了阿里云服务器)。

集成前提:开发者在集成和开发前需要了解一下常用的接入方式和架构建议,如下图所示:

图片

1、登录网页版的个人支付宝

https://auth.alipay.com/login/ant_sso_index.htm


2、进入研发服务进入沙箱环境


3、通过开发平台去配置秘钥配置

https://opendocs.alipay.com/open/200/105311


4、配置yml文件和pom

alipay:appId: 2016110300790369 #在支付宝创建的应用的idnotifyUrl: http://127.0.0.1/api/pay/notify #支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息returnUrl: http://127.0.0.1/api/page/success #同步通知,支付成功,一般跳转到成功页 http://127.0.0.1/api/page/success?charset=utf-8&out_trade_no=6837ec3c-11b5-4290-b423-54515caf2fa5&method=alipay.trade.page.pay.return&total_amount=93.80&sign=c7jnEO8n6O%2BZXpk7dF3zYtIJb9lTMIM0%2B%2FmLm2JjPgdH5vEib7wp49%2F2%2FMB05YyKOxk6PYI5B2W0k%2FdHi%2Biyk083ZKcwL3a4ToXusG%2BZji66PaYe3tIe72N%2FgzpKcxF9lwF2%2FR0%2FbPhTDJpqem2v9Ej0d1yszLVeBQzU8IuQRglM4U6ev5gt%2Bslv8BViBkXWuy2OM6pA7k6CFptHWwXBYsdg9Ik%2BAIh0LD3rZobpzyn1w7y71Bu2Nj8XHev2gzmkxjyRSuERZJVVBSNNqtGY6xxlNqzh9L5k%2B4FcwEqNv5UPgWlCnvT9BI%2FB3cCUcAUTOxcdLwi1W8gTaqeI3rStyw%3D%3D&trade_no=2020122122001400320501115075&auth_app_id=2016110300790369&version=1.0&app_id=2016110300790369&sign_type=RSA2&seller_id=2088102181741856×tamp=2020-12-21+11%3A53%3A05signType: RSA2 #签名方式charset: utf-8 #字符编码格式gatewayUrl: https://openapi.alipaydev.com/gateway.do #沙箱环境timeoutExpress: 30mformat: jsonmerchantPrivateKey: # 商户私钥alipayPublicKey: #支付宝公钥

com.alipay.sdkalipay-sdk-java4.9.28.ALLorg.jdomjdom22.0.6

5、包含网页支付(已测试)、APP支付、提现、退款、回调接口

5.1、请求入口代码

package com.example.mybaties.controller;import com.example.mybaties.result.BaseResponse;
import com.example.mybaties.result.ResultGenerator;
import com.example.mybaties.service.AliPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @description: 支付宝下单支付* @author: lst* @date: 2020-12-01 16:58*/
@RestController
@RequestMapping("/pay")
@Api(value = "AliPayController", tags = "支付宝下单支付")
public class AliPayController {@Autowiredprivate AliPayService aliPayService;/*** @Description 支付宝下单支付* @author lst* @date 2020-12-1 17:27* @return com.example.mybaties.result.BaseResponse*/@PostMapping(value = "/place-order", produces = "application/json; charset=utf-8")@ApiOperation(value = "支付宝下单支付", notes = "支付宝下单支付", produces = "application/json")public BaseResponse placeOrder() {return ResultGenerator.genSuccessResult(aliPayService.placeOrder());}/*** @Description 网页版支付宝下单支付* @author lst* @date 2020-12-2 14:16* @return com.example.mybaties.result.BaseResponse*/@PostMapping(value = "/alipay-page", produces = "application/json; charset=utf-8")@ApiOperation(value = "网页版支付宝下单支付", notes = "网页版支付宝下单支付", produces = "application/json")public void alipayPage(HttpServletResponse response) {aliPayService.alipayPage(response);}/*** @Description 支付宝提现* @author lst* @date 2020-12-2 17:03* @param response*/@PostMapping(value = "/alipay-withdraw", produces = "application/json; charset=utf-8")@ApiOperation(value = "支付宝提现", notes = "支付宝提现", produces = "application/json")public void withdraw(HttpServletResponse response) {aliPayService.withdraw(response);}/*** @Description 支付宝退款* @author lst* @date 2020-12-21 14:19* @param response*/@PostMapping(value = "/alipay-refund", produces = "application/json; charset=utf-8")@ApiOperation(value = "支付宝退款", notes = "支付宝退款", produces = "application/json")public void refund(HttpServletResponse response) {aliPayService.refund(response);}/*** @Description 支付宝支付成功后,回调该接口* @author lst* @date 2020-12-1 17:27* @param request* @param response* @return java.lang.String*/@RequestMapping(value="/notify",method={RequestMethod.POST,RequestMethod.GET})@ApiOperation(value = "支付宝支付成功后,回调该接口", notes = "支付宝支付成功后,回调该接口", produces = "application/json")public String notify(HttpServletRequest request, HttpServletResponse response) {return aliPayService.notifyData(request,response);}}

5.2、实现层代码

package com.example.mybaties.service.impl;import com.example.mybaties.form.AlipayBean;
import com.example.mybaties.form.AlipayRefundForm;
import com.example.mybaties.form.WithdrawBean;
import com.example.mybaties.service.AliPayService;
import com.example.mybaties.utils.AlipayUtil;
import com.example.mybaties.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;/*** @description: 支付宝下单支付* @author: lst* @date: 2020-12-01 17:01*/
@Service
@Slf4j
public class AliPayServiceImpl implements AliPayService {@Autowiredprivate AlipayUtil alipayUtil;/*** @Description 支付宝下单支付* @author lst* @date 2020-12-1 17:27* @return java.lang.String*/@Overridepublic String placeOrder() {String body = alipayUtil.alipay();return body;}/*** @Description 支付宝支付成功后,回调该接口* @author lst* @date 2020-12-1 17:27* @param request* @param response* @return java.lang.String*/@Overridepublic String notifyData(HttpServletRequest request, HttpServletResponse response) {return alipayUtil.notifyData(request,response);}/*** @Description 网页版支付宝下单支付* @author lst* @date 2020-12-1 17:27* @param response* @return java.lang.String*/@Overridepublic void alipayPage(HttpServletResponse response) {AlipayBean alipayBean = new AlipayBean();//商户订单号,商户网站订单系统中唯一订单号,必填alipayBean.setOut_trade_no(UUID.randomUUID().toString());//付款金额,必填alipayBean.setTotal_amount("93.8");//订单名称,必填alipayBean.setSubject("商品名称:网页版支付测试Java");//商品描述,可空alipayBean.setBody("商品信息");String payResult = alipayUtil.alipayPage(alipayBean);response.setContentType("text/html;charset=utf-8");try {response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write(payResult);response.getWriter().write("");response.getWriter().write("");response.getWriter().flush();response.getWriter().close();} catch (IOException e) {e.printStackTrace();}}/*** @Description 支付宝提现* @author lst* @date 2020-12-2 17:03* @param response* @return void*/@Overridepublic void withdraw(HttpServletResponse response) {WithdrawBean withdrawBean = new WithdrawBean();String payResult = alipayUtil.withdraw(withdrawBean);response.setContentType("text/html;charset=utf-8");try {response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");if("success".equals(payResult)){response.getWriter().write("

恭喜提现成功
");}else{response.getWriter().write("
提现失败
");}response.getWriter().write("");response.getWriter().write("");response.getWriter().flush();response.getWriter().close();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void refund(HttpServletResponse response) {AlipayRefundForm alipayRefundForm = new AlipayRefundForm();String payResult = alipayUtil.alipayRefund(alipayRefundForm);response.setContentType("text/html;charset=utf-8");try {response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");response.getWriter().write("");if(StringUtil.isNotEmpty(payResult)){response.getWriter().write("
恭喜退款成功
");}else{response.getWriter().write("
退款失败
");}response.getWriter().write("");response.getWriter().write("");response.getWriter().flush();response.getWriter().close();} catch (IOException e) {e.printStackTrace();}}
}

5.3、支付工具类

package com.example.mybaties.utils;import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.example.mybaties.constants.AlipayProperties;
import com.example.mybaties.exceptionhandler.BaseException;
import com.example.mybaties.exceptionhandler.BaseExceptionEnum;
import com.example.mybaties.form.AlipayBean;
import com.example.mybaties.form.AlipayRefundForm;
import com.example.mybaties.form.WithdrawBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;/*** @description: 支付宝支付工具* @author: lst* @date: 2020-12-01 15:57* 支付宝管理:https://open.alipay.com/platform/developerIndex.htm* 支付宝对接文档:https://opendocs.alipay.com/open/54/106370*/
@Slf4j
@Component
public class AlipayUtil {@Autowiredprivate AlipayProperties alipayProperties;/*** @Description APP支付宝下单支付* @author lst* @date 2020-12-1 17:28* @param* @return java.lang.String*/public String alipay(){//TODO 1、实例化客户端AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());//TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.payAlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();//TODO 3、SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();//商品信息model.setBody("商品信息");//商品名称model.setSubject("商品名称:App支付测试Java");//商品订单号(自动生成)model.setOutTradeNo(UUID.randomUUID().toString());//交易超时时间model.setTimeoutExpress(alipayProperties.getTimeoutExpress());//支付金额model.setTotalAmount("0.01");//销售产品码model.setProductCode("QUICK_MSECURITY_PAY");model.setTimeExpire("2020-12-21 17:52:00");request.setBizModel(model);//回调地址request.setNotifyUrl(alipayProperties.getNotifyUrl());log.info("请求数据:{},回调地址:{}",request.getBizModel(),request.getNotifyUrl());//这里和普通的接口调用不同,使用的是sdkExecuteAlipayTradeAppPayResponse respOnse= null;try {respOnse= alipayClient.sdkExecute(request);//就是orderString 可以直接给客户端请求,无需再做处理。log.info("支付宝返回数据:{}",response.getBody());} catch (AlipayApiException e) {e.printStackTrace();throw new BaseException(BaseExceptionEnum.ALIPAY_MSG_ERROR);}return response.getBody();}/*** @Description APP支付宝支付成功后,回调该接口* @author lst* @date 2020-12-1 17:29* @param request* @param response* @return java.lang.String*/public String notifyData(HttpServletRequest request, HttpServletResponse response){Map params = new HashMap();//TODO 1、从支付宝回调的request域中取值Map requestParams = request.getParameterMap();for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {String name = iter.next();String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i entry : params.entrySet()) {log.info("key:{}, value:{}",entry.getKey(),entry.getValue());}//TODO 2.封装必须参数 商户订单号 订单内容 交易状态(TRADE_SUCCESS)String outTradeNo = request.getParameter("out_trade_no");String orderType = request.getParameter("body");String tradeStatus = request.getParameter("trade_status");log.info("商户订单号:{},订单内容:{},交易状态:{}",outTradeNo,orderType,tradeStatus);//TODO 3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)try {boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayProperties.getAlipayPublicKey(), alipayProperties.getCharset(), alipayProperties.getSignType());if (signVerified) {//验签成功log.info("*******验签成功******");//TODO 业务处理逻辑return "success";} else {// 验签失败log.info("*******验签失败******");return "fail";}} catch (AlipayApiException e) {e.printStackTrace();return "fail";}}/*** @Description 网页版支付宝下单支付* @author lst* @date 2020-12-2 14:11* @param alipayBean* @return java.lang.String*/public String alipayPage(AlipayBean alipayBean){//TODO 1、实例化客户端AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());//TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay//2、创建一个支付请求 //设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();alipayRequest.setReturnUrl(alipayProperties.getReturnUrl());alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());alipayBean.setTimeout_express(alipayProperties.getTimeoutExpress());//绝对超时时间,格式为yyyy-MM-dd HH:mm:ss 2016-12-31 10:05:01//alipayBean.setTime_expire("2020-12-21 17:52:00");alipayRequest.setBizContent(JSONObject.toJSONString(alipayBean));String result = "";try {result = alipayClient.pageExecute(alipayRequest).getBody();//会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面log.info("支付宝的响应:{}",result);} catch (AlipayApiException e) {e.printStackTrace();throw new BaseException(BaseExceptionEnum.ALIPAY_MSG_ERROR);}return result;}/*** @Description 支付宝提现* @author lst* @date 2020-12-2 17:04* @param withdrawBean* @return java.lang.String*/public String withdraw(WithdrawBean withdrawBean){//提现//TODO 1、实例化客户端AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());//TODO 2、实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.payAlipayFundTransToaccountTransferRequest alipayRequest = new AlipayFundTransToaccountTransferRequest();/* "\"out_biz_no\":\"3142321423432\"," +"\"payee_type\":\"ALIPAY_LOGONID\"," +"\"payee_account\":\"abc@sina.com\"," +"\"amount\":\"12.23\"," +"\"payer_show_name\":\"上海交通卡退款\"," +"\"payee_real_name\":\"张三\"," +"\"remark\":\"转账备注\"" +" }"*///商户转账唯一订单号withdrawBean.setOut_biz_no(DateUtil.getDateTime14());withdrawBean.setPayee_type("ALIPAY_LOGONID");withdrawBean.setPayee_account("ycknrb8604@sandbox.com");withdrawBean.setPayee_real_name("ycknrb8604");withdrawBean.setAmount("22.4");withdrawBean.setPayer_show_name("");withdrawBean.setRemark("推推提现");String jsOnData= JSONObject.toJSONString(withdrawBean);log.info("支付宝提现请求数据:{}",jsonData);alipayRequest.setBizContent(jsonData);//TODO 3、转账/提现try {AlipayFundTransToaccountTransferResponse respOnse= alipayClient.execute(alipayRequest);log.info("支付宝的响应:{}",JSONObject.toJSON(response));if(response.isSuccess()){//提现成功return "success";}else {throw new BaseException(BaseExceptionEnum.ALIPAY_WITHDRAW_ERROR);}} catch (AlipayApiException e) {e.printStackTrace();throw new BaseException(BaseExceptionEnum.ALIPAY_WITHDRAW_ERROR);}}/*** @Description 支付宝退款* @author lst* @date 2020-12-21 14:12* @param alipayRefundForm* @return java.lang.String*/public String alipayRefund(AlipayRefundForm alipayRefundForm){//TODO 1、实例化客户端AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(), alipayProperties.getMerchantPrivateKey(), alipayProperties.getFormat(),alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());AlipayTradeRefundRequest aliPayRequest = new AlipayTradeRefundRequest();AlipayTradeRefundModel model = new AlipayTradeRefundModel();//订单支付时传入的商户订单号,不能和 trade_no同时为空model.setOutTradeNo("b87267c8-435b-449b-9ebb-e12efe06a1dd");//支付宝交易号,和商户订单号不能同时为空model.setTradeNo("2020122122001400320501115255");//需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数model.setRefundAmount("93.80");//退款的原因说明model.setRefundReason("正常退款");//标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。model.setOutRequestNo(DateUtil.getDateTime14());aliPayRequest.setBizModel(model);try {AlipayTradeRefundResponse aliPayRespOnse= alipayClient.execute(aliPayRequest);log.debug("aliPayResponse:{}", aliPayResponse);if (!"10000".equals(aliPayResponse.getCode())) {log.info("支付宝退款失败,支付宝交易号:{},状态码:{}", "2020122122001400320501115254", aliPayResponse.getCode());throw new BaseException(aliPayResponse.getSubMsg());}return aliPayResponse.getMsg();} catch (AlipayApiException e) {e.printStackTrace();throw new BaseException("退款失败");}}
}

5.4、支付宝支付配置信息类

package com.example.mybaties.constants;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** @description: 支付宝支付配置信息* @author: lst* @date: 2020-12-01 15:50*/
@Component
@ConfigurationProperties(prefix = "alipay")
@Data
public class AlipayProperties {/*** 在支付宝创建的应用的id*/private String appId;/*** 商户私钥,您的PKCS8格式RSA2私钥*/private String merchantPrivateKey;/*** 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。*/private String alipayPublicKey;/*** 服务器[异步通知]页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问* 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息*/private String notifyUrl;/*** 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问* 同步通知,支付成功,一般跳转到成功页*/private String returnUrl;/*** 签名方式*/private String signType;/*** 字符编码格式*/private String charset;/*** 支付宝网关; https://openapi.alipaydev.com/gateway.do 正式环境 https://openapi.alipay.com/gateway.do*/private String gatewayUrl;/*** 该笔订单允许的最晚付款时间,逾期将关闭交易*/private String timeoutExpress;/*** 请求的格式:json*/private String format;}

5.5、网页支付代码orderPage.html、下单成功代码success.html






恭喜下单成功


6、打入服务器进行测试

输入网址点击‘提交’ 按钮,后端已经默认支付数据,我用沙箱APP支付成功后可以跳转到成功页面。

手机端也可以测试


HwVideoEditor


想要源码的小伙伴可以下方留言。

 

 

 


推荐阅读
  • NTP服务器配置详解:原理与工作模式
    本文深入探讨了网络时间协议(NTP)的工作原理及其多种工作模式,旨在帮助读者全面理解NTP的配置参数和应用场景。NTP是基于RFC 1305的时间同步标准,广泛应用于分布式系统中,确保设备间时钟的一致性。 ... [详细]
  • Nginx 反向代理与负载均衡实验
    本实验旨在通过配置 Nginx 实现反向代理和负载均衡,确保从北京本地代理服务器访问上海的 Web 服务器时,能够依次显示红、黄、绿三种颜色页面以验证负载均衡效果。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 福克斯新闻数据库配置失误导致1300万条敏感记录泄露
    由于数据库配置错误,福克斯新闻暴露了一个58GB的未受保护数据库,其中包含约1300万条网络内容管理记录。任何互联网用户都可以访问这些数据,引发了严重的安全风险。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
  • 深入解析Serverless架构模式
    本文将详细介绍Serverless架构模式的核心概念、工作原理及其优势。通过对比传统架构,探讨Serverless如何简化应用开发与运维流程,并介绍当前主流的Serverless平台。 ... [详细]
  • 本文将详细介绍多个流行的 Android 视频处理开源框架,包括 ijkplayer、FFmpeg、Vitamio、ExoPlayer 等。每个框架都有其独特的优势和应用场景,帮助开发者更高效地进行视频处理和播放。 ... [详细]
  • 使用PHP实现网站访客计数器的完整指南
    本文详细介绍了如何利用PHP构建一个简易的网站访客统计系统。通过具体的代码示例和详细的解释,帮助开发者理解和实现这一功能,适用于初学者和有一定经验的开发人员。 ... [详细]
  • 本文探讨了为何相同的HTTP请求在两台不同操作系统(Windows与Ubuntu)的机器上会分别返回200 OK和429 Too Many Requests的状态码。我们将分析代码、环境差异及可能的影响因素。 ... [详细]
  • 本文详细介绍了一种通过MySQL弱口令漏洞在Windows操作系统上获取SYSTEM权限的方法。该方法涉及使用自定义UDF DLL文件来执行任意命令,从而实现对远程服务器的完全控制。 ... [详细]
  • Python + Pytest 接口自动化测试中 Token 关联登录的实现方法
    本文将深入探讨 Python 和 Pytest 在接口自动化测试中如何实现 Token 关联登录,内容详尽、逻辑清晰,旨在帮助读者掌握这一关键技能。 ... [详细]
  • 为了解决不同服务器间共享图片的需求,我们最初考虑建立一个FTP图片服务器。然而,考虑到项目是一个简单的CMS系统,为了简化流程,团队决定探索七牛云存储的解决方案。本文将详细介绍使用七牛云存储的过程和心得。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
author-avatar
明天流浪远方
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有