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

Spring Cloud Gateway 常见过滤器的基本使用

目录

1. 过滤器的作用

2. Spring Cloud Gateway 过滤器的类型

2.1 内置过滤器

2.1.1 AddResponseHeader

2.1.2 AddRequestHeader

2.1.3 PrefixPath

2.1.4 RequestRateLimiter

2.1.5 Retry

2.2 自定义过滤器


1. 过滤器的作用

过滤器通常用于拦截、处理或修改数据流和事件流,在数据流中执行特定的操作或转换。

过滤器主要在以下几个方面发挥作用:

  1. 功能扩展和定制:过滤器允许您自定义和扩展网关的功能,以满足特定需求,如请求和响应的修改、路由规则的动态配置等。

  2. 数据校验和过滤:通过过滤器,您可以检查、验证和过滤传入或传出的数据,确保请求和响应的合法性和一致性。

  3. 安全保护:过滤器可以用于实施安全策略,如认证、授权、防止攻击等,以增强网关的安全性。

  4. 性能优化:通过过滤器,您可以对请求和响应进行性能优化,如缓存、压缩、请求路由的智能选择,以提高网关的性能。

  5. 统一处理:过滤器允许您在网关层面执行共享的处理逻辑,如日志记录、监控、审计等,以确保整个微服务体系的一致性和可维护性。

  6. 逻辑复用:通过过滤器,您可以将一些常见的操作抽象出来,以实现逻辑的复用,减少重复代码和维护工作。

2. Spring Cloud Gateway 过滤器的类型

Spring Cloud Gateway 过滤器可以分为两大类:

1. 内置过滤器

  • 局部的内置过滤器
  • 全局的内置过滤器

2. 自定义过滤器

2.1 内置过滤器

内置过滤器常见的有以下几种:

  1. AddResponseHeader
  2. AddRequestHeader
  3. AddRequestParameter(和 AddRequestHeader 相似)
  4. PrefixPath
  5. RequestRateLimiter
  6. Retry

Spring Cloud Gateway 过滤器常见有这么几种,实际上它有30多种,可以借助官方文档加以了解:Spring Cloud Gateway

过滤器又分为前置过滤器后置过滤器

在目标方法返回之前执行的过滤器就叫做前置过滤器(AddRequestXXX),在目标方法返回之后执行的过滤器就叫做后置过滤器。(AddResponseXXX)

前置工作:准备 user-service 和 order-service 两个模块,并且配置好 naocs 连接信息。

① user-service:创建一个 controller

@RestController
@RequestMapping("/user")
public class UserController {@Autowired  // 获取动态端口private ServletWebServerApplicationContext context;@RequestMapping("/getname")public String getName() {return context.getWebServer().getPort() +"--UserService:name=java-"+new Random().nextInt(100);}
}
server.port=0
spring.application.name=user-service-gateway
spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos

② order-service:创建一个 controller

@RestController
@RequestMapping("/order")
public class OrderController {@RequestMapping("/getcount")public int getCount() {return new Random().nextInt(1000);}
}
server.port=0
spring.application.name=order-service-gateway
spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos

2.1.1 AddResponseHeader

spring:cloud:nacos: # 配置注册中心discovery:server-addr: localhost:8848username: nacospassword: nacosgateway: # 配置网关routes:- id: userserviceuri: lb://user-service-gateway   # loadbalancerpredicates:- Path=/user/**filters:- AddResponseHeader=My-Resp-Header, www.baidu
server:port: 10086

在配置过滤器之前,我在网关服务中引入 Nacos 和 LoadBalancer 之后,使用10086 端口去访问userservice服务时,查看对应的响应头:

配置了 AddResponseHeader 过滤器之后,再去访问userservice服务时,查看对应的响应头:

上述的设置,设置的是局部过滤器,如果此时在网关服务中再新增一组 id (如下),此时再去访问order-service服务时,响应头中就不会包含 My-Resp-Header 这个标头了。

spring:cloud:gateway: # 配置网关routes:- id: userservice  # 用户服务uri: lb://user-service-gateway   # loadbalancerpredicates:- Path=/user/**filters:- AddResponseHeader=My-Resp-Header, www.baidu- id: orderservice  # 订单服务uri: lb://order-service-gatewaypredicates:- Path=/order/**

此时还想访问 orderservice 服务时,也在响应头中看到对应的标头,要么就把 filters 照搬到下面,但是这样做,代码就不具备维护性了,发生修改的时候,这将会是一个体力活;要么就使用全局过滤器。

全局过滤器的配置

spring:cloud:gateway: # 配置网关routes:- id: userservice  # 用户服务uri: lb://user-service-gateway   # loadbalancerpredicates:- Path=/user/**filters:- AddResponseHeader=My-Resp-Header, www.baidu- id: orderservice  # 订单服务uri: lb://order-service-gatewaypredicates:- Path=/order/**default-filters:  # 全局过滤器- AddResponseHeader=MyApplication-Resp-Header, gateway.org

2.1.2 AddRequestHeader

spring:cloud:nacos: # 配置注册中心discovery:server-addr: localhost:8848username: nacospassword: nacosgateway: # 配置网关routes:- id: userservice  # 用户服务uri: lb://user-service-gateway   # loadbalancerpredicates:- Path=/user/**filters:- AddResponseHeader=My-Resp-Header, www.baidudefault-filters:- AddRequestHeader=My-Req-Marking, www.baidu

如何拿到前置过滤器,可以在 userservice 服务里边写一个打印请求头的 controller:

@RequestMapping("/print-header")
public void printHeader(HttpServletRequest request) {Enumeration<String> headers = request.getHeaderNames();while(headers.hasMoreElements()) {String key = headers.nextElement();String value = request.getHeader(key);System.out.println(key +": " + value);}
}

此时运行userservice 和 gateway,去反问 print-header 接口, 查看 userservice 的控制台:

2.1.3 PrefixPath

spring:cloud:nacos: # 配置注册中心discovery:server-addr: localhost:8848username: nacospassword: nacosgateway: # 配置网关routes:- id: userserviceuri: lb://user-service-gatewaypredicates:- Path=/user/**filters:- PrefixPath=/v2

假设此时 userservice 中的 UserController 升级为了 v2 版本,但是我的接口 /user/** 已经 对外公布了,此时还想让 localhost:10086/user/getname 访问到 v2 版本的 controller,肯定是不允许再修改后端的接口了,也不能让前端跟着改,使用 PrefixPath 就可以很好的调整。

第一版代码:

@RestController
@RequestMapping("/user")
public class UserController {@Autowired  // 获取动态端口private ServletWebServerApplicationContext context;@RequestMapping("/getname")public String getName() {return context.getWebServer().getPort() +"--UserService:name=java-"+new Random().nextInt(100);}
}

第二版代码: 

@RequestMapping("/v2/user")
@RestController
public class UserControllerV2 {@Autowired  // 获取动态端口private ServletWebServerApplicationContext context;@RequestMapping("/getname")public String getName() {return context.getWebServer().getPort() +"--V2:UserService:name=java-"+new Random().nextInt(10);}
}

当我们配置了 PrefixPath 之后,再使用原来的 localhost:10086/user/getname 去访问服务的时候,就可以正常的访问到 v2 版本的 controller 了,无需再去修改前后端接口。

2.1.4 RequestRateLimiter

这是 Spring Cloud Gateway 内置的网关限流过滤器,它使用了令牌桶的限流算法。

令牌桶限流算法:令牌桶限流算法通过固定速率生成令牌放入桶中,桶满则丢弃新令牌。请求到来时消耗令牌进行处理,桶内无令牌则等待或丢弃请求,从而平滑流量,防止网络拥堵。

Spring Cloud  Gateway 当前版本支持和 Redis 一起实现限流功能,Spring Cloud Gateway 选择 Redis 作为限流方案的一个重要支撑是因为 Redis 的一些特性可以很好地满足限流中对于性能、一致性和分布式处理的要求。

  1. 分布式环境:在微服务架构中,服务实例往往是分布式部署的,Redis 由于其天然的分布式特性,能够确保在不同的服务实例之间共享限流的状态,实现全局限流。

  2. 性能:Redis 是一个高性能的内存数据库,它的读写速度非常快,可以达到每秒数十万次的读写请求。这种性能上的优势使得 Redis 成为实现限流中维护和检查速率限制状态的理想选择。

  3. 原子操作:Redis 支持多种原子操作,这对于计数器来说非常重要。例如,使用 INCRDECR 命令递增或递减计数器,可以保证即使在高并发的情况下,计数器的值也是准确的。

  4. 过期策略:Redis 允许为数据设置生存时间(TTL),这对于限流算法中的时间窗口非常有用。例如,在固定时间窗口算法中,可以设置令牌或计数器在特定时间后自动过期。

它的实现步骤总共分为三步:

  1. 添加 Redis 框架依赖
  2. 创建限流规则
  3. 配置限流过滤器

a.添加 Redis 框架依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

注意事项:Redis版本太低,此功能设置会无效,建议使用 Redis 版本 5.x+。

b.创建限流规则

限流规则,既可以针对某一个 IP 做限流,也可以针对 URL 进行限流(所有的 IP 访问 URL 都会限流)

创建一个类,根据IP进行限流:

@Component
public class IpAddressKeyResolver implements KeyResolver {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());}
}

创建一个类,根据URL进行限流:

@Component
public class UrlKeyResolver implements KeyResolver {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {// 获取请求的URI路径作为限流的keyString path = exchange.getRequest().getURI().getPath();return Mono.just(path);}
}

c.设置限流过滤器

spring:cloud:nacos: # 配置注册中心discovery:server-addr: localhost:8848username: nacospassword: nacosgateway: # 配置网关routes:- id: userserviceuri: lb://user-service-gatewaypredicates:- Path=/user/**filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1  # 每秒请求数redis-rate-limiter.burstCapacity: 1  # 最大请求数key-resolver: "#{@ipAddressKeyResolver}"  # spEL表达式data:redis:host: 127.0.0.1port: 16379database: 0

注意,内置的限流过滤器 name 必须等于"RequestRateLimiter" ,其他参数的含义如下:

1. redis-rate-limiter.replenishRate:令牌填充速度(每秒允许请求数)

2. redis-rate-limiter.burstCapacity:令牌桶容量(最大令牌数)

3. key-resolver:根据哪个 key 进行限流,它的值是 spEL 表达式。

这三步完成之后,就表示每个 IP  每秒钟只能访问一次,如果刷新页面刷新的太快,就会出现如下页面:

2.1.5 Retry

在 OpenFeign 里面呢,也有个 Retry 超时重试,而且它还可以自定义重试规则,为什么 Gateway 还要有一个 Retry 呢 ?

OpenFeign里面的重试机制是服务调用层面的,它是用来帮助服务消费者处理调用远程服务时的问题的。而Spring Cloud Gateway的重试机制是在网关层面上,主要用于对所有通过网关的服务调用提供统一的重试策略,以处理上游服务可能出现的不稳定性(网络抖动)。两者虽都提供重试功能,但服务的层次不同,因此它们在微服务架构中各有其作用。

请求重试过滤器配置案例:

spring:cloud:nacos: # 配置注册中心discovery:server-addr: localhost:8848username: nacospassword: nacosgateway: # 配置网关routes:- id: userserviceuri: lb://user-service-gatewaypredicates:- Path=/user/**filters:- name: Retry  # 重试过滤器args:retries: 3statuses: GATEWAY_TIMEOUTmethods: GETseries: SERVER_ERRORbackoff:firstBackoff: 10ms  # 第一次重试间隔maxBackoff: 50ms  # 最大重试间隔factor: 2  # firstBack * (factor ^ n)   # 重试系数basedOnPreviousValue: false  # 基于上次重试时间加上重试系数来计算

注意,重试过滤器的 name 必须等于 "Retry" ,因为 "Retry" 就是内置重试过滤器的名字,改为其他框架就无法识别了;其他参数的含义如下:

1. retries:尝试的重试次数。

2. statuses:重试的HTTP状态码。取值参考:HttpStatus (Spring Framework 6.1.2 API)

3. methods:重试的HTTP方法。取值:GET(默认值),HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE。

4. series:要重试的一系列状态码。默认值是 SERVER_ERROR,值是 5,表示 5xx,( 5开头的状态码)。共有 5 个取值:

  • 1xx:INFORMATIONAL
  • 2xx:SUCCESSFUL
  • 3xx:REDIRECTION
  • 4xx:CLIENT_ERROR
  • 5xx:SERVER_ERROR

5. backoff:配置的重试策略。

  • firstBackoff:第一次的重试间隔
  • maxBackoff:最大重试间隔
  • factor:重试系数,firstBackoff *(factor ^ n),n= 1,2,3,4...
  • basedOnPreviousValue:默认关闭,如果设为 true,就表示基于上次的重试时间加上重试系数来计算,例如 firstBackoff 为 10,假设上一次重试是 10 * 2 ^ 1,那么下一次就不是 10 * 2 ^ 2,而是 20 * 2 ^ 2。

【案例演示】

在 userservice 服务中,写一个接口去触发 GATEWAY_TIMEOUT:

@RequestMapping("/504")
public void return504(HttpServletResponse response) {System.out.println("------- Do return504 method. ------");response.setStatus(504);
}

启动 userservice 模块和 gateway 模块,此时 userservice 服务自动注入到 nacos 中,使用原生服务接口访问:

原生服务接口:192.168.10.83:63129/user/504,触发 504 

此时查看控制台 :打印了一次

再使用 Gateway 网关去访问 userservice 服务, localhost:10086/user/504,触发 504

此时查看控制台:打印了 4 次(清除上面的打印后)

可见重试过滤器确实生效了。

【注意事项】

1. 此处的超时重试和 OpenFeign 里面的超时重试不太一样,这里设置重试 3 次,就是真的重试 3 次,加上触发重试的 1 次,总共就是打印 4 次,而 OpenFeign 里面的超时重试,重试次数的下标是从 1 开始的,所以在 OpenFeign 里面,这样设置,只会重试 2 次,打印 3 次。

2. 上面重试过滤器的配置,像 method、series 这种参数,它都是有默认值的,比如说 series 的默认值是 5 开头的状态码,那么即使我们不设置这个参数,当我们触发 5 开头的异常时,并且没有与其他设置的参数相悖的时候,也会触发超时重试功能。

2.2 自定义过滤器

代码案例:使用 Spring Cloud Gateway 提供的全局过滤器实现统一认证授权。

@Component
public class AuthFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange,   // 执行的事件GatewayFilterChain chain)     // 过滤器链{// 未登录判断逻辑,当参数中 username=admin && password=admin 继续执行,// 否则退出执行// 得到 Request 对象 (reactive web)ServerHttpRequest request = exchange.getRequest();// 得到 Response 对象 (reactive web)ServerHttpResponse response = exchange.getResponse();String username = request.getQueryParams().getFirst("username");String password = request.getQueryParams().getFirst("password");if (username != null && username.equals("admin")&& password != null && password.equals("admin")) {// 已经登录,执行下一步return chain.filter(exchange);} else {// 设置无权限 401response.setStatusCode(HttpStatus.UNAUTHORIZED);// 执行完成,不用继续执行后续流程了return response.setComplete();}}
}

在访问相对应服务的时候,可以先不加用户名密码试一次,它会触发 401,再加上 username=admin&password=admin,就可以正常访问到相应服务了。

当有多个过滤器时,我们还可以给过滤器指定它的执行顺序:

假如说,此时有两个过滤器,一个用来验证登录,一个用来验证是否有权限。那么这个时候,需要先验证登录,才会再去验证是否有权限。如何实现?

  1. 实现 Ordered 接口
  2. 重写 getOrder 方法
@Override
public int getOrder() {// 此值越小越先执行return 1;
}

相关文章:

Spring Cloud Gateway 常见过滤器的基本使用

目录 1. 过滤器的作用 2. Spring Cloud Gateway 过滤器的类型 2.1 内置过滤器 2.1.1 AddResponseHeader 2.1.2 AddRequestHeader 2.1.3 PrefixPath 2.1.4 RequestRateLimiter 2.1.5 Retry 2.2 自定义过滤器 1. 过滤器的作用 过滤器通常用于拦截、处理或修改数据流和事…...

maven依赖无法传递问题排查

一、背景 在A模块中引入B模块&#xff0c;C服务引入A模块但是B模块没有传递进来。 二、排查 使用mvn clean install -Dmaven.test.skiptrue查看打包日志信息&#xff0c;通过搜索A模块名称&#xff0c;出现如下警告信息&#xff1a; [WARING] The POM for A:jar:0.0.1-SNAP…...

JVM钩子

JVM钩子 简介 在Java应用程序中&#xff0c;可以通过注册关闭钩子&#xff08;Shutdown Hook&#xff09;函数来实现在JVM关闭时执行特定的代码。关闭钩子是一种用于在JVM关闭时执行清理任务的机制&#xff0c;它允许开发者在JVM关闭之前执行一些必要的清理工作&#xff0c;如…...

linux cat命令增加-f显示文件名功能

在使用cat命令配合grep批量搜索文件内容时&#xff0c;我仅仅能知道是否搜索到&#xff0c;不知道是在哪个文件里找到的。比如cat ./src/*.c | grep full_write,在src目录下的所有.c文件里找full_write,能匹配到所有的full_write&#xff0c;但是不知道它们分别在哪些文件里。于…...

linux更改登录shell

从bash修改成python 在/etc/passwd下可以更改用户登录bash 例 root:x:0:0:root:/root:/bin/bash //更改bin/bash为/bin/python&#xff0c;就可以用root登录python页面了从python修改成bash 方法一 重启页面按e进入内核编辑模式linux16这行后添加&#xff1a;init/bin/…...

【JS】报错:Uncaught TypeError: Cannot read properties of null (reading ‘classList‘)

错误展示 今天写js代码的时候遇到报错&#xff1a; 源代码&#xff1a; <ul class"slider-indicator"><li class"active"></li><li></li><li></li><li></li><li></li><li><…...

kali2.0安装VMware Tools 和自定义改变分辨率

kali2.0安装VMware Tools 和自定义改变分辨率 VMware Tools 简介&#xff1a;VMware Tools安装&#xff1a;自定义改变分辨率&#xff1a;xrandr命令修改分辨率&#xff1a; 前言&#xff1a; 因为kali2.0比较老 所以需要手动安装 WMware Tools 进行复制粘贴操作&#xff01; …...

redis中根据通配符删除key

redis中根据通配符删除key 我们是不是在redis中keys user:*可以获取所有key&#xff0c;但是 del user:*却不行这里我提供的命令主要是SCANSCAN 0 MATCH user:* COUNT 100使用lua保证原子性 SCAN参数描述 在示例中&#xff0c;COUNT 被设置为 100。这是一个防止一次性获取大…...

【HDFS联邦(2)】HDFS Router-based Federation官网解读:HDFSRouterFederation的架构、各组件基本原理

文章目录 一. 介绍二、HDFS Router-based Federation 架构1. 示例说明2. Router2.1. Federated interface2.2. Router heartbeat2.3. NameNode heartbeat2.4. Availability and fault toleranceInterfaces 3. Quota management4. State Store 三、部署 ing 本文主要参考官网&am…...

【头歌实训】Spark 完全分布式的安装和部署

文章目录 第1关&#xff1a; Standalone 分布式集群搭建任务描述相关知识课程视频Spark分布式安装模式示例集群信息配置免密登录准备Spark安装包配置环境变量修改 spark-env.sh 配置文件修改 slaves 文件分发安装包启动spark验证安装 编程要求测试说明答案代码报错问题基本过程…...

Leetcode—86.分隔链表【中等】

2023每日刷题&#xff08;六十九&#xff09; Leetcode—86.分隔链表 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* partition(struct ListNode* head, int x) {struct ListNode…...

淘宝/天猫商品API:实时数据获取与安全隐私保护的指南

一、引言 随着电子商务的快速发展&#xff0c;淘宝/天猫等电商平台已成为商家和消费者的重要交易场所。对于电商企业而言&#xff0c;实时掌握店铺商品的销售情况、库存状态等信息至关重要。然而&#xff0c;手动管理和更新商品信息既费时又费力。因此&#xff0c;淘宝/天猫提…...

使用 SSH 方式实现 Git 远程连接GitHub

git是目前世界上最先进的分布式版本控制系统&#xff0c;相比于SVN&#xff0c;分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在&#xff0c;也就是有没有联网都可以正常工作&#xff01;当有网络的时候&#xff0c;再把本地提交推送一下就完成了同步&…...

Centos7部署Keepalived+lvs服务

IP规划&#xff1a; 服务器IP地址主服务器20.0.0.22/24从服务器20.0.0.24/24Web-120.0.0.26/24Web-220.0.0.27/24 一、主服务器安装部署keepalivedlvs服务 1、调整/proc响应参数 关闭Linux内核的重定向参数&#xff0c;因为LVS负载服务器和两个页面服务器需要共用一个VIP地…...

12/31

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;用于密集预测的多路径视觉Transformer1、研究背景2、方法提出3、相关方法3.1、Vision Transformers for dense predictions3.2、C…...

python使用openpyxl为excel模版填充数据,生成多个Sheet页面

目标&#xff1a;希望根据一个给定的excel模版&#xff0c;生成多个Sheet页面&#xff0c;比如模版&#xff1a; 示例程序 import openpyxlexcel_workbook openpyxl.load_workbook("模版.xlsx") for _i in range(3): # 比如填充3个页面# 复制模版sheet页&#x…...

基于ssm的4S店预约保养系统开发+vue论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…...

【Git】Git的基本操作

前言 Git是当前最主流的版本管理器&#xff0c;它可以控制电脑上的所有格式的文件。 它对于开发人员&#xff0c;可以管理项目中的源代码文档。&#xff08;可以记录不同提交的修改细节&#xff0c;并且任意跳转版本&#xff09; 本篇博客基于最近对Git的学习&#xff0c;简单介…...

【超图】SuperMap iClient3D for WebGL/WebGPU —— 数据集合并缓存如何控制对象样式

作者&#xff1a;taco 最近在支持的过程中&#xff0c;遇到了一个新问题&#xff01;之前研究功能的时候竟然没有想到。通常我们控制单个对象的显隐、颜色、偏移的参数都是根据对象所在的图层以及对象单独的id来算的。那么问题来了&#xff0c;合并后的图层。他怎么控制单个对象…...

intellij IDEA开发工具的使用(打开/关闭工程;删除类文件;修改类/包/模块/项目名称;导入/删除模块)

1&#xff0c;打开工程 打开IDEA&#xff0c;会看到如下界面 1栏目里是自己曾经打开过的project&#xff08;工程&#xff09;&#xff0c;直接点击就好。如果需要打开其他工程&#xff0c;则点击open&#xff0c;会出下以下界面。 选择需要加载的project&#xff08;工程&…...

抖音详情API:开发环境搭建与工具选择

随着短视频的流行&#xff0c;抖音已经成为了一个备受欢迎的社交媒体平台。对于开发人员而言&#xff0c;利用抖音详情API开发定制化的抖音应用具有巨大的潜力。本文将为你详细介绍开发抖音应用的开发环境搭建与工具选择&#xff0c;帮助你顺利地开始开发工作。 一、开发环境搭…...

IntelliJ IDEA [插件 MybatisX] mapper和xml间跳转

文章目录 1. 安装插件2. 如何使用3. 主要功能总结 MybatisX 是一款为 IntelliJ IDEA 提供支持的 MyBatis 开发插件 它通过提供丰富的功能集&#xff0c;大大简化了 MyBatis XML 文件的编写、映射关系的可视化查看以及 SQL 语句的调试等操作。本文将介绍如何安装、配置和使用 In…...

Havenask 分布式索引构建服务 --Build Service

Havenask 是阿里巴巴智能引擎事业部自研的开源高性能搜索引擎&#xff0c;深度支持了包括淘宝、天猫、菜鸟、高德、饿了么在内几乎整个阿里的搜索业务。本文针对性介绍了 Havenask 分布式索引构建服务——Build Service&#xff0c;主打稳定、快速、易管理&#xff0c;是在线系…...

vscode软件安装步骤

目录 一、下载软件安装包 二、运行安装包后 一、下载软件安装包 打开vscode官方网址&#xff0c;找到下载界面 链接如下&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 我是windows电脑&#xff0c;各位小伙伴自己选择合适的版本&#xff0c;点击下载按钮…...

C语言中灵活多变的动态内存,malloc函数 free函数 calloc函数 realloc函数

文章目录 &#x1f680;前言&#x1f680;管理动态内存的函数✈️malloc函数✈️free函数✈️calloc函数✈️realloc函数 &#x1f680;在使用动态内存函数时的常见错误✈️对NULL指针的解引用✈️ 对动态开辟空间的越界访问✈️对非动态开辟内存使用free释放✈️使用free释放一…...

小细节处理

重载运算符&#xff1a;重载<运算符。 bool operator<(const Edge&s)const{return w<s.w;}...

【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…...

Python正则的匹配与替换

import re 查找时的注意事项&#xff0c;要查找的内容左右两边打出来&#xff0c;用真正的字符&#xff0c;不要用.*?&#xff0c;离查找内容远一点&#xff0c;再用.*? a /aksj<a>哈哈哈<a><p>拉阿鲁<p>\.askjp b re.findall(<a>(.*?)<…...

解决ELement-UI懒加载三级联动数据不回显(天坑)

最老是遇到这类问题头有点大,最后也是解决了,为铁铁们总结了一下几点 一.查看数据类型是否一致 未选择下 选择下 二.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式 三.绑定v-if 确保每次重新加载 四.绑定key 五.完整代码...

【数据结构和算法】找出两数组的不同

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 哈希类算法题注意事项 2.2 方法一&#xff1a;哈希法 三、代码 3.1 方法一&#xff1a;哈希法 四…...

基于Python的B站排行榜大数据分析与可视化系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 本文介绍了一项基于Python的B站排行榜大数据分析与可视化系统的研究。通过网络爬虫技术&#xff0c;系统能够自动分析B站网址&#xff0c;提取大量相关文本信息并存储在系统中。通过对这些信息进行…...

MySQL一些常用命令

1、登录本地MySQL #一种是 mysql -u root -p; #(输入密码后回车)#另一种是 mysql -uroot -p123456; #(在-p后面直接带上密码)2、启动MySQL服务 net start mysql; 3、关闭MySQL服务&#xff1a; net stop mysql; 4、创建数据库 create database 数据库名; 5、创建数据…...

WPF 新手指引弹窗

新手指引弹窗介绍 我们在第一次使用某个软件时&#xff0c;通常会有一个“新手指引”教学引导。WPF实现“新手指引”非常方便&#xff0c;且非常有趣。接下来我们就开始制作一个简单的”新手指引”(代码简单易懂&#xff0c;便于移植)&#xff0c;引用到我们的项目中又可添加一…...

py注册登录界面

代码分析 引入tkinter库&#xff0c;并从中导入messagebox模块。 read_users()函数用于读取存储用户信息的文本文件"users.txt"。它打开文件并逐行读取&#xff0c;将每行的用户名和密码以空格分隔后存储在一个列表中&#xff0c;最后返回该列表。 login(username,…...

基于电商场景的高并发RocketMQ实战-Consumer端队列负载均衡分配机制、并发消费以及消费进度提交

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…...

【Java开发岗面试】八股文—数据库MySQLRedis

声明&#xff1a; 背景&#xff1a;本人为24届双非硕校招生&#xff0c;已经完整经历了一次秋招&#xff0c;拿到了三个offer。本专题旨在分享自己的一些Java开发岗面试经验&#xff08;主要是校招&#xff09;&#xff0c;包括我自己总结的八股文、算法、项目介绍、HR面和面试…...

IntelliJ IDEA [设置] 隐藏 .idea 等 .XXX 文件夹

文章目录 1. 问题描述2. 解决办法3. 最后效果4. 特殊处理&#xff08;正常不需要此步骤&#xff09;总结 我们使用 IntelliJ IDEA 导入项目的时候&#xff0c;经常会看到一些 .XXX 的文件夹&#xff08;例如&#xff1a;.idea&#xff0c;.mvn&#xff0c;.gradle 等&#xff0…...

每日一题——LeetCode961

方法一 排序法&#xff1a; 2*n长度的数组里面有一个元素重复了n次&#xff0c;那么将数组排序&#xff0c;求出排序后数组的中间值&#xff08;因为长度是偶数&#xff0c;没有刚好的中间值&#xff0c;默认求的中间值是偏左边的那个&#xff09;那么共有三种情况&#xff1a;…...

基于Unity Editor开发一个技能编辑器可能涉及到的内容

基于Unity Editor开发一个技能编辑器&#xff0c;涉及到的方面较多&#xff0c;涵盖了Unity自身的GUI框架、序列化系统、自定义编辑器、脚本调用与数据存储等。下面是几个关键点和你可能会用到的类以及API&#xff1a; 自定义Inspector&#xff1a; 使用Editor类来重写组件的I…...

Ubuntu 22.04 安装ftp实现与windows文件互传

Ubuntu 22.04 安装ftp实现与windows文件互传 1、配置安装 安装&#xff1a; sudo apt install vsftpd -y使能开机自启&#xff1a; sudo systemctl enable vsftpd 启动&#xff1a; sudo systemctl start vsftpd创建ftp工作目录&#xff1a; sudo mkdir -p /home/ftp/uftp…...

EasyPoi使用案例

EasyPoi使用案例 easypoi旨在简化Excel和Word的操作。基于注解的导入导出&#xff0c;修改注解就可以修改Excel&#xff1b;支持常用的样式自定义&#xff1b;基于map可以灵活定义表头字段&#xff1b;支持一对多的导入导出&#xff1b;支持模板的导出&#xff1b;支持HTML/Exc…...

分布式系统架构设计之分布式数据存储的分类和组合策略

在现下科技发展迅猛的背景下&#xff0c;分布式系统已经成为许多大规模应用和服务的基础架构。分布式架构的设计不仅仅是一项技术挑战&#xff0c;更是对数据存储、管理和处理能力的严峻考验。随着云原生、大数据、人工智能等技术的崛起&#xff0c;分布式系统对于数据的高效存…...

javaEE -18(11000字 JavaScript入门 - 3)

一&#xff1a;事件 &#xff08;高级&#xff09; 1.1 注册事件&#xff08;绑定事件&#xff09; 给元素添加事件&#xff0c;称为注册事件或者绑定事件&#xff0c;注册事件有两种方式&#xff1a;传统方式和方法监听注册方式 传统注册方式 &#xff1a; 利用 on 开头的…...

LangChain.js 实战系列:入门介绍

&#x1f4dd; LangChain.js 是一个快速开发大模型应用的框架&#xff0c;它提供了一系列强大的功能和工具&#xff0c;使得开发者能够更加高效地构建复杂的应用程序。LangChain.js 实战系列文章将介绍在实际项目中使用 LangChain.js 时的一些方法和技巧。 LangChain.js 是一个…...

pyCharm 打印控制台中文乱码解决办法

解决方法 在 "File" -> "Settings" 中的控制台设置&#xff1a; 在 "File" -> "Settings" 中&#xff0c;你可以找到 "Editor" -> "General" -> "Console"。在这里&#xff0c;你可能会找到…...

计算机基础--Linux详解

一概述 Linux是一种自由和开放源码的类UNIX操作系统。它是由林纳斯托瓦兹于1991年首次发布的&#xff0c;并从那时起在全球范围内得到了广泛的应用和开发。Linux具有强大的可定制性&#xff0c;可以运行在各种硬件平台上&#xff0c;包括x86、ARM、MIPS等。它不仅广泛应用于服…...

基于OpenAI的Whisper构建的高效语音识别模型:faster-whisper

1 faster-whisper介绍 faster-whisper是基于OpenAI的Whisper模型的高效实现&#xff0c;它利用CTranslate2&#xff0c;一个专为Transformer模型设计的快速推理引擎。这种实现不仅提高了语音识别的速度&#xff0c;还优化了内存使用效率。faster-whisper的核心优势在于其能够在…...

cfa一级考生复习经验分享系列(十六)

写在前面&#xff1a;并不鼓励大家在考前一个月才开始复习&#xff0c;不过&#xff0c;既然已经逼到了绝境&#xff0c;灰心丧气也没有用&#xff0c;不如放手一搏&#xff01; 首先说一下我的背景&#xff0c;工作金融机构的it&#xff0c;和cfa基本没关系&#xff0c;本硕计…...

数模学习day05-插值算法

插值算法有什么作用呢&#xff1f; 答&#xff1a;数模比赛中&#xff0c;常常需要根据已知的函数点进行数据、模型的处理和分析&#xff0c;而有时候现有的数据是极少的&#xff0c;不足以支撑分析的进行&#xff0c;这时就需要使用一些数学的方法&#xff0c;“模拟产生”一些…...

hive中struct相关函数总结

目录 hive官方函数解释示例实战 hive官方函数解释 hive官网函数大全地址&#xff1a;添加链接描述 Return TypeNameDescriptionstructstruct(val1, val2, val3, …)Creates a struct with the given field values. Struct field names will be col1, col2, …structnamed_str…...