Springboot——对接支付宝实现扫码支付

文章目录

  • 前言
  • 官方文档以及说明
    • 1、申请沙箱
    • 2、进入沙箱获取对应的关键信息
    • 3、拿到系统生成的公钥和密钥
  • 注意事项
  • 创建springboot项目
    • 1、引入依赖
    • 2、配置连接参数
    • 3、创建配置类,用于接收这些参数
    • 4、中间类的定义(订单类)
    • 5、编写测试接口
      • 场景一、pc端请求后端后,生成支付宝的特制页面(AlipayTradePagePayRequest)
      • 场景二、前端请求后端,只返回对应的二维码地址(AlipayTradePrecreateRequest)

前言

最近项目中需要对接支付模块,需要考虑到微信支付与支付宝支付的实现。

由于微信支付的还在审核中,先预研demo做一个支付宝支付码获取的实现。

官方文档以及说明

本次开发环境中编写demo实现,采用的是支付宝的沙箱方式,后续上线会重新申请正式的appid等信息。

支付宝开发平台链接:https://open.alipay.com/

1、申请沙箱

进入支付宝的开发平台,用支付宝登录后,在控制台面板中找到沙箱,并创建第一个沙箱。

https://open.alipay.com/develop/manage

在这里插入图片描述

2、进入沙箱获取对应的关键信息

在这里插入图片描述
对于像授权回调地址应用网关地址这些暂时不设置。

3、拿到系统生成的公钥和密钥

在这里插入图片描述
在这里插入图片描述
这里会有应用公钥支付宝公钥应用私钥。但这里通过个人实践,只需要支付宝公钥应用私钥

应用公钥在某些特定的场景中并不会生效还会出现各种奇怪的报错。

注意事项

沙箱并不是所有的操作都能够在其中进行开发操作,详情参考官方文档说明。

https://opendocs.alipay.com/common/097jyi?pathHash=9fcbe0d0&highlight_field=%E6%B2%99%E7%AE%B1%E7%8E%AF%E5%A2%83

在这里插入图片描述

创建springboot项目

1、引入依赖

选用的是springboot 2.x 的版本,并且引用的依赖在官方文档中有版本说明。

<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.34.47.ALL</version>
</dependency><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.0.0</version>
</dependency>

参考官方文档依赖版本规定:

https://opendocs.alipay.com/common/02n6z6?pathHash=f5e2a056

其中,针对通用版的版本要求,官方文档中有做说明:

https://opendocs.alipay.com/common/02kkv2?pathHash=358ff034

在这里插入图片描述

2、配置连接参数

src/main/resources中新建一个application.yml文件,如果是nacos项目,可以在对应的配置中心中新增配置项。

# 支付宝支付
alipay:# 应用ID,标识你的应用appId: # 应用私钥,用于签名请求appPrivateKey:# 应用公钥,用于验证支付宝的响应#alipayPublicKey: 沙箱页面中的应用公钥# 支付宝公钥(推荐使用这个)alipayPublicKey: 支付宝公钥# 支付通知的回调地址,支付宝会在支付完成后通知这个地址notifyUrl: 支付成功后的回调地址,必须要求公网能够访问# 页面跳转地址,支付完成后跳转到此URLreturnUrl: 场景一中登录成功后的重定向页面# 签名类型,通常为RSA2signType: RSA2# 字符编码,通常为utf-8charset: utf-8# 支付宝网关地址,用于发送请求gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do

3、创建配置类,用于接收这些参数

package cn.alipay.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 支付宝 支付参数配置类*/
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {/*** APPID*/private String appId;/*** 应用私钥,就是工具生成的应用私钥*/public String appPrivateKey;/*** 支付宝公钥,对应APPID下的支付宝公钥*/public String alipayPublicKey;/*** 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息*/public String notifyUrl;/*** 同步通知,支付成功,一般跳转到成功页*/public String returnUrl;/*** 签名方式*/private String signType;/*** 字符编码格式*/private String charset;/*** 支付宝网关;https://openapi-sandbox.dl.alipaydev.com/gateway.do*/public String gatewayUrl;/*** 订单超时时间*/private String timeout = "5m";
}

新建配置类,获取对应的配置参数,并构建连接对象

package cn.alipay.config;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.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.domain.SettleDetailInfo;
import com.alipay.api.domain.SettleInfo;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;/*** 支付宝支付 模板*/
@Slf4j
@Data
@Component
public class AliPayTemplate {@Autowiredprivate AlipayProperties alipayProperties;private AlipayClient alipayClient;@PostConstructpublic void init() {log.info("APPID:" + alipayProperties.getAppId());log.info("应用私钥:" + alipayProperties.getAppPrivateKey());log.info("支付宝公钥:" + alipayProperties.getAlipayPublicKey());log.info("支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息:" + alipayProperties.getNotifyUrl());log.info("同步通知,支付成功,一般跳转到成功页:" + alipayProperties.getReturnUrl());log.info("签名方式:" + alipayProperties.getSignType());log.info("字符编码格式:" + alipayProperties.getCharset());log.info("订单超时时间:" + alipayProperties.getTimeout());log.info("支付宝网关:" + alipayProperties.getGatewayUrl());// 1. 根据支付宝的配置生成一个支付客户端alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(),alipayProperties.getAppPrivateKey(),"json",alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType());}
}

4、中间类的定义(订单类)

创建一个订单类,主要用于一些基本信息的传参处理。

package cn.alipay.config;import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** 订单表*/
@Data
public class Order implements Serializable {/*** 订单Id*/private Long id;/*** 用户Id*/private Long userId;/*** 接口Id*/private Long interfaceInfoId;/*** 支付金额*/private Double money;/*** 支付方式*/private String paymentMethod;/*** 0 - 未支付 1 - 已支付*/private Integer status;/*** 创建时间*/private Date createTime;/*** 更新时间*/private Date updateTime;/*** 是否删除*/private Integer isDelete;private static final long serialVersionUID = 1L;
}

5、编写测试接口

场景一、pc端请求后端后,生成支付宝的特制页面(AlipayTradePagePayRequest)

在支付宝的PC端案例文档中,有一个注意事项。

https://opendocs.alipay.com/open/00dn7o?pathHash=c1e36251

在这里插入图片描述
像这种传递订单信息至后台,后台调用支付宝的对应接口后,返回前端页面样式或者地址,前端再进行渲染实现。可以参照以下的方式。

定义接口

package cn.alipay.controller;import cn.alipay.config.AliPayTemplate;
import cn.alipay.config.Order;
import com.alipay.api.AlipayApiException;
import com.alipay.easysdk.factory.Factory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;/*** 阿里支付宝支付与回调接口*/
@Slf4j
@RestController
@RequestMapping("/alipay")
public class AliPayController {@Autowiredprivate AliPayTemplate aliPayTemplate;/*** 获取支付宝* post 请求 生成 frame 页面* get 请求生成 页面url* @param id* @return* @throws AlipayApiException*/@GetMapping(value = "/pay", produces = MimeTypeUtils.TEXT_HTML_VALUE)@ResponseBodypublic String pay(@RequestParam long id) throws AlipayApiException {// 创建订单对象并设置属性Order order = createOrder(id);// 调用支付宝支付模板进行支付return aliPayTemplate.pay(order);}/*** 伪造订单数据* @param id* @return*/private Order createOrder(long id) {Order order = new Order();order.setId(id);  order.setUserId(1111111L);  order.setInterfaceInfoId(294389472934L); order.setMoney(1000.0);  order.setPaymentMethod("支付宝"); return order;}
}

定义请求逻辑代码

package cn.alipay.config;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.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.domain.SettleDetailInfo;
import com.alipay.api.domain.SettleInfo;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;/*** 支付宝支付 模板*/
@Slf4j
@Data
@Component
public class AliPayTemplate {@Autowiredprivate AlipayProperties alipayProperties;private AlipayClient alipayClient;@PostConstructpublic void init() {log.info("APPID:" + alipayProperties.getAppId());log.info("应用私钥:" + alipayProperties.getAppPrivateKey());log.info("支付宝公钥:" + alipayProperties.getAlipayPublicKey());log.info("支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息:" + alipayProperties.getNotifyUrl());log.info("同步通知,支付成功,一般跳转到成功页:" + alipayProperties.getReturnUrl());log.info("签名方式:" + alipayProperties.getSignType());log.info("字符编码格式:" + alipayProperties.getCharset());log.info("订单超时时间:" + alipayProperties.getTimeout());log.info("支付宝网关:" + alipayProperties.getGatewayUrl());// 1. 根据支付宝的配置生成一个支付客户端alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(),alipayProperties.getAppPrivateKey(),"json",alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType());}/*** 调用支付接口* @param order* @return* @throws AlipayApiException*/public String pay(Order order) throws AlipayApiException {//2、创建一个支付请求,并设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();alipayRequest.setReturnUrl(alipayProperties.getReturnUrl());alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());Long id = order.getId();Long interfaceInfoId = order.getInterfaceInfoId();Double money = order.getMoney();String paymentMethod = order.getPaymentMethod();// 设置业务内容,包含必要的支付参数AlipayTradePagePayModel pagePayModel = new AlipayTradePagePayModel();pagePayModel.setOutTradeNo(String.valueOf(id));pagePayModel.setTotalAmount(String.valueOf(money));pagePayModel.setSubject(String.valueOf(interfaceInfoId));pagePayModel.setBody(paymentMethod);pagePayModel.setTimeoutExpress(alipayProperties.getTimeout());// 电脑支付场景下仅支持FAST_INSTANT_TRADE_PAYpagePayModel.setProductCode("FAST_INSTANT_TRADE_PAY");alipayRequest.setBizModel(pagePayModel);// post 请求返回 frame 前端样式AlipayTradePagePayResponse response = alipayClient.pageExecute(alipayRequest, "POST");// get 请求返回一个页面地址urlAlipayTradePagePayResponse response2 = alipayClient.pageExecute(alipayRequest, "GET");String result = response.getBody();//返回支付宝响应的结果return result;}
}

启动服务,请求后的效果如下:

localhost:8080/alipay/pay?id=123456

post 请求生成的样式如下所示:

<form  name="punchout_form" method="post" action="会有对应的信息"><input  type="hidden" name="biz_content" value="{&quot;body&quot;:&quot;支付宝&quot;,&quot;out_trade_no&quot;:&quot;125477&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;,&quot;subject&quot;:&quot;294389472934&quot;,&quot;timeout_express&quot;:&quot;5m&quot;,&quot;total_amount&quot;:&quot;1000.0&quot;}"><input  type="submit" value="立即支付" style="display:none" ></form><script>document.forms[0].submit();</script>

在这里插入图片描述
如果是GET请求,则只会是上面action的地址。

场景二、前端请求后端,只返回对应的二维码地址(AlipayTradePrecreateRequest)

参照官方文档中的案例实现

https://opendocs.alipay.com/open/8ad49e4a_alipay.trade.precreate?scene=2ae8516856f24a5592194d237f3f235d&pathHash=d18bff53

编写对应的接口和实现类

@GetMapping(value = "/pay3")
@ResponseBody
public String pay3(@RequestParam long id) throws AlipayApiException {// 创建订单对象并设置属性Order order = createOrder(id);// 调用支付宝支付模板进行支付return aliPayTemplate.pay3(order);
}
package cn.alipay.config;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.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.BusinessParams;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.domain.SettleDetailInfo;
import com.alipay.api.domain.SettleInfo;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;/*** 支付宝支付 模板*/
@Slf4j
@Data
@Component
public class AliPayTemplate {@Autowiredprivate AlipayProperties alipayProperties;private AlipayClient alipayClient;@PostConstructpublic void init() {log.info("APPID:" + alipayProperties.getAppId());log.info("应用私钥:" + alipayProperties.getAppPrivateKey());log.info("支付宝公钥:" + alipayProperties.getAlipayPublicKey());log.info("支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息:" + alipayProperties.getNotifyUrl());log.info("同步通知,支付成功,一般跳转到成功页:" + alipayProperties.getReturnUrl());log.info("签名方式:" + alipayProperties.getSignType());log.info("字符编码格式:" + alipayProperties.getCharset());log.info("订单超时时间:" + alipayProperties.getTimeout());log.info("支付宝网关:" + alipayProperties.getGatewayUrl());// 1. 根据支付宝的配置生成一个支付客户端alipayClient = new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppId(),alipayProperties.getAppPrivateKey(),"json",alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType());}public String pay3(Order order) throws AlipayApiException {AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();// 强制关闭 ssl 证书校验WebUtils.setNeedCheckServerTrusted(false);alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());JSONObject jsonObject = new JSONObject();jsonObject.put("out_trade_no",order.getId());// 商户订单号jsonObject.put("total_amount",order.getMoney());// 商品价格jsonObject.put("subject","这只是个商品标题");// 商品标题jsonObject.put("store_id","香蕉集团");//组织或公司名
//            jsonObject.put("timeout_express","5m");// 订单有效时间alipayRequest.setBizContent(jsonObject.toString());AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);System.out.println("创建订单结果:"+response.getBody());System.out.println("订单编号是"+response.getOutTradeNo());String qrCode = response.getQrCode();
//            AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();return qrCode;}
}

请求后会得到一个支付的地址,使用ZXing框架,将其转换为二维码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3923.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

迪杰斯特拉算法

迪杰斯特拉算法 LeetCode 743. 网络延迟时间 https://blog.csdn.net/xiaoxi_hahaha/article/details/110257368 import sysdef dijkstra(graph, source):"""dijkstra算法:param graph: 邻接矩阵:param source: 出发点&#xff0c;源点:return:""&…

STL学习-容器适配器

一.stack栈 1.栈的介绍 stack 栈是一种只在一端(栈顶)进行数据插入(入栈)和删除(出栈)的数据结构,它满足后进 先出(LIFO)的特性。 使用push(入栈)将数据放入stack,使用pop(出栈)将元素从容器中移除。 栈的结构如图&#xff1a; 在头文件<stack>中&#xff0c;class st…

【C语言】动态内存开辟

写在前面 C语言中有不少开辟空间的办法&#xff0c;但是在堆上开辟的方法也就只有动态内存开辟&#xff0c;其访问特性与数组相似&#xff0c;但最大区别是数组是开辟在栈上&#xff0c;而动态内存开辟是开辟在堆上的。这篇笔记就让不才娓娓道来。 PS:本篇没有目录实在抱歉CSD…

海的记忆:海滨学院班级回忆录项目

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

【VScode】C/C++多文件夹下、多文件引用、分别编译——仅一个设置【适合新人入手】

【VScode】C/C多文件夹内的多文件引用编译 1、问题2、前提&#xff08;最简环境&#xff09;3、核心&#xff08;关键配置&#xff09;4、成功享用~ 1、问题 在使用 VScode 编写一个简单项目的时候&#xff0c;没有特别配置的情况下&#xff0c;若主文件(.c)引用了自定义的头文…

62 mysql 中 存储引擎MyISAM 中索引的使用

前言 固定数据表 mysql. tables_priv 的表结构创建如下 CREATE TABLE tables_priv (Host char(60) COLLATE utf8_bin NOT NULL DEFAULT ,Db char(64) COLLATE utf8_bin NOT NULL DEFAULT ,User char(32) COLLATE utf8_bin NOT NULL DEFAULT ,Table_name char(64) COLLATE u…

使用buildx构建多架构平台镜像

1. 查看buildx插件信息 比较新的docker-ce版本默认已经集成了buildx插件 [rootdocker ~]# docker buildx version github.com/docker/buildx v0.11.2 9872040 [rootdocker ~]#2. 增加多平台镜像构建支持 通过tonistiigi/binfmt:latest初始化一个基于容器的构建环境&#xff…

数据库基础(3) . Navicat使用

0.下载安装 官网 : https://www.navicat.com.cn/ Navicat 中国 | 支持 MySQL、Redis、MariaDB、MongoDB、SQL Server、SQLite、Oracle 和 PostgreSQL 的数据库管理 1.连接数据库 1.1.连接 1.1.1.点击连接 打开navicat 点击 左上角连接 1.1.2.选择MySQL 弹出配置界面 1.1…

MySQL(上)

一、SQL优化 1、如何定位及优化SQL语句的性能问题&#xff1f;创建的索引有没有被使用到?或者说怎么才可以知道这条语句运行很慢的原因&#xff1f; 对于性能比较低的sql语句定位&#xff0c;最重要的也是最有效的方法其实还是看sql的执行计划&#xff0c;而对于mysql来说&a…

国密SM2 非对称加解密前后端工具

1.依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.21</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpki…

【银河麒麟操作系统】软raid重建速度限制问题分析

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 现象描述 遇到软raid重建速度问题&#xff0c;分…

ssm教室信息管理系统+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码看文章最下面 需要定制看文章最下面 目 录 目 录 III 1 绪论 1 1.1 研究背景 1 1.2目的和意义 1 1.3 论文结构安排 2 2 相关技术 3 …

去中心化存储:Web3中的数据安全新标准

随着Web3的兴起&#xff0c;去中心化存储逐渐成为数据安全的新标准。传统的中心化存储方式将数据集中保存在少数服务器上&#xff0c;这种模式尽管在早期互联网中被广泛应用&#xff0c;但随着数据量和数据价值的增加&#xff0c;其潜在的安全风险和隐私问题也逐渐暴露。而去中…

Ubuntu 22 安装 Apache Doris 3.0.3 笔记

Ubuntu 22 安装 Apache Doris 3.0.3 笔记 1. 环境准备 Doris 需要 Java 17 作为运行环境&#xff0c;所以首先需要安装 Java 17。 sudo apt-get install openjdk-17-jdk -y sudo update-alternatives --config java在安装 Java 17 后&#xff0c;可以通过 sudo update-alter…

安卓摄像头的详细使用

安卓摄像头的详细使用 一、引言二、权限设置三、打开摄像头四、摄像头的属性设置&#xff08;一&#xff09;预览尺寸&#xff08;二&#xff09;图片格式&#xff08;三&#xff09;对焦模式 五、摄像头预览六、拍照功能七、视频录制 一、引言 在安卓开发中&#xff0c;摄像头…

服务器的配置复杂,租用时该如何选择参数?

对于互联网企业来说&#xff0c;开发一套可以接入互联网的产品&#xff0c;并利用它来盈利是终极目的。但互联网产品必须有服务器才能运行&#xff0c;对于很多公司来说&#xff0c;托管服务器成本太高&#xff0c;而租用服务器才算得上是最好的选择&#xff0c;但面对配置参数…

10min本地安装Qwen1.5-0.5B-Chat

大模型系列文章 本地电脑离线部署大模型 配置&#xff1a;MAC-M1-8GB 10min本地安装Qwen1.5-0.5B-Chat 大模型系列文章前言一、下载Qwen1.5-0.5B-Chat二、构造函数chatBot.py三、启动命令1、放置脚本2、启动命令3、效果图 前言 在人工智能领域&#xff0c;大模型无疑是最炙手…

90%会展主办方都会用的6款数字化工具

在会展行业&#xff0c;数字化转型已成为提升竞争力的关键。面对日益增长的运营成本和收入增长的瓶颈&#xff0c;主办方需要借助数字化工具来实现效率提升和成本控制。 今天介绍几种常见的数字化工具和应用方式。 一、线上展览平台 构建线上展览平台是会展主办方拓展线上销…

弃用 RestTemplate,来了解一下官方推荐的 WebClient !

在 Spring Framework 5.0 及更高版本中&#xff0c;RestTemplate 已被弃用&#xff0c;取而代之的是较新的 WebClient。这意味着虽然 RestTemplate 仍然可用&#xff0c;但鼓励 Spring 开发人员迁移到新项目的 WebClient。 WebClient 优于 RestTemplate 的原因有几个&#xff…

SpringBoot+Thymeleaf电商系统

> 这是一个基于SpringBootThymeleafBootstrap实现的简单电商系统。 > 实现了用户浏览、添加购物车、商品管理等功能&#xff0c;并支持响应式布局。 > 本项目适合JAVA初学者作为入门学习项目 一、部分界面演示 二、技术栈 技术栈中文描述Spring Boot快速开发框架…