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

springboot和flask整合nacos,使用openfeign实现服务调用,使用gateway实现网关的搭建(附带jwt续约的实现)

环境准备:

插件版本
jdk21
springboot

3.0.11

springcloud

2022.0.4

springcloudalibaba

2022.0.0.0

nacos2.2.3(稳定版)
python3.8

nacos部署(docker)

先创建目录,分别创建config,logs,data目录,单独创建一个容器

docker run -d \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
-p 7848:7848 \
-v /data/nacos/conf:/mnt/data3/dockerfiles/nacos/config \
-v /data/nacos/logs:/mnt/data3/dockerfiles/nacos/logs \
-v /data/nacos/data:/mnt/data3/dockerfiles/nacos/data \
--name nacos-mysql \
--restart=always \
nacos/nacos-server:v2.2.3

 将配置文件拷贝出来(主要是application.properties和logback.xml)

docker cp nacos-mysql:/home/nacos/conf ./

修改mysql的信息(修改文件application.properties)

再次运行

docker run -d \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
-p 7848:7848 \
-v /data/nacos/conf:/mnt/data3/dockerfiles/nacos/config \
-v /data/nacos/logs:/mnt/data3/dockerfiles/nacos/logs \
-v /data/nacos/data:/mnt/data3/dockerfiles/nacos/data \
--name nacos-mysql \
--restart=always \
nacos/nacos-server:v2.2.3

开启服务器端口:

centos开启防火墙端口 

 访问 ip:port/nacos

出现此页面即为安装成功。

springboot注册到nacos

先贴一个pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.11</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>platform</artifactId><version>0.0.1-SNAPSHOT</version><name>platform</name><description>platform</description><properties><java.version>21</java.version><spring-cloud.version>2022.0.0</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.2</version></dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!--        </dependency>--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.2</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.2</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>edge-SNAPSHOT</version></dependency><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.41</version></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><repositories><repository><id>projectlombok.org</id><url>https://projectlombok.org/edge-releases</url></repository></repositories><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件bootstrap.yml

spring:application:name: platformcloud:nacos:server-addr: ip:portconfig:file-extension: ymlgroup: DEFAULT_GROUPprefix: ${sping.application.name}

springboot启动类

@SpringBootApplication
@EnableFeignClients
@EnableCaching
@EnableScheduling
@EnableDiscoveryClient
@RefreshScope
public class PlatformApplication {public static void main(String[] args) {SpringApplication.run(PlatformApplication.class, args);}}

启动后就可以将服务注册到nacos中

python集成flask注册到nacos

首先下载nacos的sdk包

pip install nacos-sdk-python

python代码

import glob
import nacos
import threading
from flask import request, send_file
from flask import Flask, Response# nacos注册中心配置
SERVER_ADDRESS = "http://ip:port"
client = nacos.NacosClient(SERVER_ADDRESS)def service_register():"""ephemeral参数:是否是临时服务,应为false; 刚才上面也提到了,如果是 非临时实例,客户端就无需主动完成心跳检测。因此此处将服务注册为 非临时实例"""client.add_naming_instance("train", "ip", "port", ephemeral=False)# 测试nacos
@app.route("/testNacos/<testId>", methods=["GET"])
def testNacos(testId):resMap = {}print("nacos: {}".format(testId))resMap["code"] = "200"resMap["message"] = "hello nacos"resMap["data"] = str(testId)response = Response(json.dumps(resMap), status=200,content_type='application/json')return responseif __name__ == "__main__":# main()threading.Timer(5, service_register).start()app.run("0.0.0.0", 12352)

启动后就可以将服务注册到nacos中

到这里,服务注册到nacos已经完成了

使用openfeign进行服务间的调用

@FeignClient("train")
public interface InferRpcService {@GetMapping("/testNacos/{testId}")VitsResponse testNacos(@PathVariable String testId);
}

测试类

@Test
public void testNacosPy(){System.out.println(trainService.testNacos("232323"));
}

执行后

 

经测试没有问题

gateway网关服务

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.11</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>gateway</artifactId><version>0.0.1-SNAPSHOT</version><name>gateway</name><description>gateway</description><properties><java.version>21</java.version><spring-cloud.version>2022.0.4</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.41</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件(bootstrap.yml)

spring:application:name: gatewaycloud:nacos:server-addr: ip:portconfig:file-extension: ymlgroup: DEFAULT_GROUPprefix: ${sping.application.name}gateway:# 下游服务https配置httpclient:ssl:use-insecure-trust-manager: trueroutes:- id: platformuri: lb://platformpredicates:- Path=/api/platform/**filters:- StripPrefix=2

启动类

@RefreshScope
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}}

jwt续约

工具类

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;import java.time.LocalDateTime;
import java.util.*;@Slf4j
public class JWTUtils {private static final String SING = "auth";public static String getToken(Map<String, String> map) {Calendar instance = Calendar.getInstance();instance.add(Calendar.MINUTE, 30);JWTCreator.Builder builder = JWT.create();map.forEach((k, v) -> {builder.withClaim(k, v);});String token = builder.withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(SING));return token;}public static DecodedJWT verify(String token) {return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);}/*** 查看是否需要续约** @param jwtToken 前端的* @return -1过期,不需要续约  0 不需要操作  1 需要续约*/public static int renewed(String jwtToken) {DecodedJWT verify = null;try {verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(jwtToken);if (Objects.nonNull(verify)) {log.info("过期时间: {}", verify.getExpiresAt());Date date = verify.getExpiresAt();if (date.before(new Date())) {log.info("token已过期");return -1;} else if (DateUtils.toLocalDateTime(date).minusMinutes(15L).isAfter(LocalDateTime.now())) {log.info("token处于正常状态");return 0;} else if (DateUtils.toLocalDateTime(date).minusMinutes(15L).isBefore(LocalDateTime.now())) {log.info("token需要续签");return 1;}}} catch (JWTVerificationException | IllegalArgumentException e) {log.info("token已过期");return -1;}log.info("token已过期");return -1;}public static String doRenewed(String number) {Map<String, String> map = Collections.singletonMap("openid", number);return getToken(map);}
}
public class DateUtils {public static LocalDateTime toLocalDateTime(Date date){return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();}
}

全局过滤器

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.gateway.constant.Constant;
import com.example.gateway.constant.LoginConstant;
import com.example.gateway.constant.VitsCloneConstant;
import com.example.gateway.dto.response.CommonResponse;
import com.example.gateway.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();// 获取请求路径String path = request.getPath().toString();log.info("path:{}", path);// 当前过滤器只处理语音克隆相关的请求if (StringUtils.contains(path, VitsCloneConstant.API_PREFIX)) {// 如果是登录接口,直接放行if (StringUtils.contains(path, LoginConstant.LOGIN_PATH)) {return chain.filter(exchange);}// 获取请求头中的Authorization字段String token = request.getHeaders().getFirst(LoginConstant.AUTHORIZATION_HEADER);// 如果校验失败,返回未授权状态if (StringUtils.isEmpty(token)) {CommonResponse<String> error = CommonResponse.error("无效的授权信息", "无效的授权信息");response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.writeWith(Mono.just(response.bufferFactory().wrap(JSON.toJSONBytes(error))));}int renewed = JWTUtils.renewed(token);if (renewed == -1) {log.info("token已过期");CommonResponse<String> error = CommonResponse.error("无效的授权信息", "无效的授权信息");response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.writeWith(Mono.just(response.bufferFactory().wrap(JSON.toJSONBytes(error))));} else if (renewed == 0) {log.info("jwtToken状态正常,无需操作");DecodedJWT verify = JWTUtils.verify(token);String openid = verify.getClaims().get("openid").asString();ServerHttpRequest modifiedRequest = exchange.getRequest().mutate().header("openId", openid).build();return chain.filter(exchange.mutate().request(modifiedRequest).build());} else {DecodedJWT verify = JWTUtils.verify(token);String openid = verify.getClaims().get("openid").asString();log.info("当前需要续约的jwtToken的用户手机号码: {}", openid);token = JWTUtils.doRenewed(openid);response.getHeaders().set(LoginConstant.AUTHORIZATION_HEADER, token);ServerHttpRequest modifiedRequest = exchange.getRequest().mutate().header("openId", openid).build();return chain.filter(exchange.mutate().request(modifiedRequest).build());}}return chain.filter(exchange);}@Overridepublic int getOrder() {return -900;}}

常量类

public interface Constant {String TOKEN = "token";
}
public interface LoginConstant {String LOGIN_PATH = "/login";String AUTHORIZATION_HEADER = "token";
}
public interface VitsCloneConstant {String API_PREFIX="/api/platform/";
}

启动网关后,就可以通过网关访问服务了

相关文章:

springboot和flask整合nacos,使用openfeign实现服务调用,使用gateway实现网关的搭建(附带jwt续约的实现)

环境准备&#xff1a; 插件版本jdk21springboot 3.0.11 springcloud 2022.0.4 springcloudalibaba 2022.0.0.0 nacos2.2.3&#xff08;稳定版&#xff09;python3.8 nacos部署&#xff08;docker&#xff09; 先创建目录&#xff0c;分别创建config&#xff0c;logs&#xf…...

深入浅出排序算法之基数排序

目录 1. 前言 1.1 什么是基数排序⭐⭐⭐ 1.2 执行流程⭐⭐⭐⭐⭐ 2. 代码实现⭐⭐⭐ 3. 性能分析⭐⭐ 3.1 时间复杂度 3.2 空间复杂度 1. 前言 一个算法&#xff0c;只有理解算法的思路才是真正地认识该算法&#xff0c;不能单纯记住某个算法的实现代码&#xff01; 1.…...

CSS选择器、CSS属性相关

CSS选择器 CSS属性选择器 通过标签的属性来查找标签&#xff0c;标签都有属性 <div class"c1" id"d1"></div>id值和class值是每个标签都自带的属性&#xff0c;还有另外一种&#xff1a;自定义属性 <div class"c1" id"d1&…...

设计模式(21)中介者模式

一、介绍&#xff1a; 1、定义&#xff1a;中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;它通过引入一个中介者对象来降低多个对象之间的耦合度。在中介者模式中&#xff0c;各个对象之间不直接进行通信&#xff0c;而是通过中介者对象…...

JVM虚拟机:通过一个例子解释JVM中栈结构的使用

代码 代码解析 main方法执行&#xff0c;创建栈帧并压栈。 int d8&#xff0c;d为局部变量&#xff0c;是基础类型&#xff0c;它位于虚拟机栈的局部变量表中 然后创建了一个TestDemo的对象&#xff0c;这个对象在堆中&#xff0c;并且这个对象的成员变量&#xff08;day&am…...

会自动写代码的AI大模型来了!阿里云推出智能编码助手通义灵码

用大模型写代码是什么样的体验&#xff1f;10月31日&#xff0c;杭州云栖大会上&#xff0c;阿里云对外展示了一款可自动编写代码的 AI 助手&#xff0c;在编码软件的对话窗口输入“帮我用 python 写一个飞机游戏”&#xff0c;短短几秒&#xff0c;这款名为“通义灵码”的 AI …...

如何公网远程访问本地WebSocket服务端

本地websocket服务端暴露至公网访问【cpolar内网穿透】 文章目录 本地websocket服务端暴露至公网访问【cpolar内网穿透】1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功…...

python 练习 在列表元素中合适的位置插入 输入值

目的&#xff1a; 有一列从小到大排好的数字元素列表&#xff0c; 现在想往其插入一个值&#xff0c;要求&#xff1a; 大于右边数字小于左边数字 列表元素&#xff1a; [1,4,6,13,16,19,28,40,100] # 方法&#xff1a; 往列表中添加一个数值&#xff0c;其目的方便元素位置往后…...

企业级JAVA、数据库等编程规范之命名风格 —— 超详细准确无误

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信你对这两篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) &#x1f4dc; 表白墙/留言墙 —— 初级SpringBoot项目&#xff0c;练手项目前后端开发(带完整源码) 全方位全步骤手把手教学 &#x1f4dc; 用户登录前后端…...

有什么可以自动保存微信收到的图片和视频的方法么

8-1 在一些有外勤工作的公司里&#xff0c;经常会需要在外面工作的同事把工作情况的图片发到指定微信或者指定的微信群里&#xff0c;以记录工作进展等&#xff0c;或者打卡等&#xff0c;对于外勤人员来说&#xff0c;也就发个图片的事&#xff0c;但是对于在公司里收图片的人…...

面试算法46:二叉树的右侧视图

题目 给定一棵二叉树&#xff0c;如果站在该二叉树的右侧&#xff0c;那么从上到下看到的节点构成二叉树的右侧视图。例如&#xff0c;图7.6中二叉树的右侧视图包含节点8、节点10和节点7。请写一个函数返回二叉树的右侧视图节点的值。 分析 既然这个题目和二叉树的层相关&a…...

vite配置terser,压缩代码及丢弃console

...

R语言使用surveyCV包对NHANES数据(复杂调查加权数据)进行10折交叉验证

美国国家健康与营养调查&#xff08; NHANES, National Health and Nutrition Examination Survey&#xff09;是一项基于人群的横断面调查&#xff0c;旨在收集有关美国家庭人口健康和营养的信息。 地址为&#xff1a;https://wwwn.cdc.gov/nchs/nhanes/Default.aspx 既往咱们…...

WOS与CNKI数据库的citespace分析教程及常见问题解决

本教程为面向新手的基于citespace的数据可视化教程&#xff0c;旨在帮助大家更快了解行业前沿的研究内容。 获取最新版本的citespace软件 在citespace官网下载最新的版本&#xff08;如果是老版本&#xff0c;可能会提示让你去官网更新为最新版&#xff0c;老版本不再提供服务…...

NEFU数字图像处理(三)图像分割

一、图像分割的基本概念 1.1专有名词 前景和背景 在图像分割中&#xff0c;我们通常需要将图像分为前景和背景两个部分。前景是指图像中我们感兴趣、要分割出来的部分&#xff0c;背景是指和前景不相关的部分。例如&#xff0c;对于一张人物照片&#xff0c;人物就是前景&…...

UEditorPlus v3.6.0 图标补全,精简代码,快捷操作重构,问题修复

UEditor是由百度开发的所见即所得的开源富文本编辑器&#xff0c;基于MIT开源协议&#xff0c;该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。 UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器&#xff0c;主要做了样式的定制&#xff0c;更符…...

C++ Set

定义 set不同于vector,strin,list这种存储容器&#xff0c;set是一种关联式容器&#xff0c;底层是搜二叉&#xff1b; 功能 set可以确定唯一的值&#xff0c;可以排序去重。 接口 insert() #include <iostream> #include<set> using namespace std;int main…...

基于知识库的chatbot或者FAQ

背景 最近突然想做一个基于自己的知识库&#xff08;knowlegebase&#xff09;的chatbot或者FAQ的项目。未来如果可以在公司用chatgpt或者gpt3.5之后的模型的话&#xff0c;还可以利用gpt强大的语言理解力和搜索出来的用户问题的相关业务文档来回答用户在业务中的问题。 Chat…...

ZOC8 for Mac:超越期待的终端仿真器

在Mac上&#xff0c;一个优秀的终端仿真器是每位开发者和系统管理员的必备工具。ZOC8&#xff0c;作为一款广受好评的终端仿真器&#xff0c;以其强大的功能和易用性&#xff0c;已经在Mac用户中积累了良好的口碑。本文将为您详细介绍ZOC8的各项特性&#xff0c;以及为什么它会…...

织梦dedecms后台档案列表显示空白或显示不了文章的解决方法

织梦dedecms后台档案列表显示空白或显示不了文章的解决方法 dede/content_list.php空白解决方法如下 dede/content_list.php空白 在DEDE后台可以查看栏目文章&#xff0c;但是所有档案列表却为空白或者显示不了文章,如图所示&#xff1a; 后来找到dede/content_list.php,看了下…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验

2024年初&#xff0c;人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目&#xff08;一款融合大型语言模型能力的云端AI编程IDE&#xff09;时&#xff0c;技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力&#xff0c;TRAE在WayToAGI等…...

SOC-ESP32S3部分:30-I2S音频-麦克风扬声器驱动

飞书文档https://x509p6c8to.feishu.cn/wiki/SKZzwIRH3i7lsckUOlzcuJsdnVf I2S简介 I2S&#xff08;Inter-Integrated Circuit Sound&#xff09;是一种用于传输数字音频数据的通信协议&#xff0c;广泛应用于音频设备中。 ESP32-S3 包含 2 个 I2S 外设&#xff0c;通过配置…...

解决MybatisPlus使用Druid1.2.11连接池查询PG数据库报Merge sql error的一种办法

目录 前言 一、问题重现 1、环境说明 2、重现步骤 3、错误信息 二、关于LATERAL 1、Lateral作用场景 2、在四至场景中使用 三、问题解决之道 1、源码追踪 2、关闭sql合并 3、改写处理SQL 四、总结 前言 在博客&#xff1a;【写在创作纪念日】基于SpringBoot和PostG…...