Nacos网关gateway的断言,自定义断言,过滤器使用
lipiwang 2024-12-01 00:41 5 浏览 0 评论
接上次网关的初步搭架成功后,看看断言和过滤器的如何操作。
上篇文章环境搭建已经ok,这次是在上篇的基础上开始操作。
上篇说了断言主要是配置文件中的application-dev.properties配置文件中spring.cloud.gateway.routes[0].predicates[0]的属性配置,上次我们只使用Path路径的断言,其实还有很多关键字可以使用
#设置路由断言,代理servicerId为provider-xg的/provider-xg/路径
spring.cloud.gateway.routes[0].predicates[0]=Path=/provider-route/**
先搭好环境:Nacos注册中心,调用服务
不清楚的朋友可以看看前面的帖子
开始根据规则来进行断言
因为规则太多我把对应规则的成功例子列出,测试几个,有兴趣的朋友可以自行测试其他。
#设置路由断言
#Path 代表路径断言
spring.cloud.gateway.routes[0].predicates[0]=Path=/provider-route/**
#After 代表时间之后都可以访问的断言
spring.cloud.gateway.routes[0].predicates[1]=After=2022-08-31T23:59:59.789+08:00[Asia/Shanghai]
#After 代表时间之前都可以访问的断言
spring.cloud.gateway.routes[0].predicates[2]=Before=2022-12-31T23:59:59.789+08:00[Asia/Shanghai]
#Method 代表支持方法类型,可支持多个,逗号分隔
spring.cloud.gateway.routes[0].predicates[3]=Method=Get,Post
#RemoteAddr 代表支持ip的断言支持多个,逗号分隔
spring.cloud.gateway.routes[0].predicates[4]=RemoteAddr=10.45.12.61,10.45.12.63
#自定义断言
spring.cloud.gateway.routes[0].predicates[5]=Test=dxg
#请求转发时会拦截路径/provider-route开头的,并且去掉/provider-route再开始转发到对应微服务接口,1的意思去掉一个前缀,2就是去掉俩个
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1
我们测试下时间断言:
把After改为当前时间之后,因为时间没到,会访问失败,应该访问不了,改为今年12月
spring.cloud.gateway.routes[0].predicates[1]=After=2022-12-31T23:59:59.789+08:00[Asia/Shanghai]
访问测试:正常报错,断言成功,其他断言大家自行测试
下面列出我目前接触到的规则:
- Path 代表路径断言
- After 代表时间之后都可以访问的断言
- After 代表时间之前都可以访问的断言
- Method 代表支持方法类型,可支持多个,逗号分隔
- RemoteAddr 代表支持远程地址的断言支持多个,逗号分隔
- Cookie:接收两个参数, cookie 名字和一个正则表达式。判断请求cookie是否具有给定名称且值与正则表达式匹配。
spring.cloud.gateway.routes[0].predicates[3]=Cookie=chocolate, ch.
- Header :接收两个参数,标题名称和正则表达式。 判断请求Header 是否具有给定名称且值与正则表达式匹配。 key value
spring.cloud.gateway.routes[0].predicates[n]=Header=X-Request-Id, \d+
- Host :接收一个参数,主机名模式。判断请求的Host 是否满足匹配规则。
spring.cloud.gateway.routes[0].predicates[n]=Host=**.hostName.org
- Query :接收两个参数,请求 param 和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。
spring.cloud.gateway.routes[0].predicates[n]=Query=xg, dag.
- 基于路由权重的断言工厂 Weight:接收一个 [ 组名 , 权重 ], 然后对于同一个组内的路由按照权重转发
spring.cloud.gateway.routes[0].predicates[n]=Weight= groupName, 9
如果上述规则不满足需求的话还可以自定义断言
先说一个场景,只支持某个人来访问接口,这时候我们需要定制化一个断言。
自定义断言有几个要求:
1.必须继承AbstractRoutePredicateFactory
2.类名称必须xxx加上RoutePredicateFactory作为结尾,其中xxx就是路由断言新增的配置规则,可以在断言中添加
3.shortcutFieldOrder方法绑定路由中的配置,即可去读
4.通过apply进行逻辑判断 true就是匹配成功 false匹配失败
现在贴上实现类代码:
package com.gateway.predicate;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* @author xg
*/
@Component
public class TestRoutePredicateFactory extends AbstractRoutePredicateFactory<TestRoutePredicateFactory.Config> {
public TestRoutePredicateFactory() {
super(TestRoutePredicateFactory.Config.class);
}
//读取配置文件中的内容并配置给配置类中的属性,即新增的断言配置项
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("name");
}
@Override
public Predicate<ServerWebExchange> apply(TestRoutePredicateFactory.Config config) {
return (exchange) -> {
// 从请求中获取配置项,也可配置在其他地方获取,看个人需求
String name = exchange.getRequest().getQueryParams().getFirst("name");
if(StringUtils.isNotEmpty(name)){
if(name.equals(config.getName())) {
return true;
}
}
return false;
};
}
@Data
@NoArgsConstructor
public static class Config{
private String name;
}
}
根据自定义断言类建立,我们就产生新的断言规则关键字,这个关键字其实就是自定义断言名称去掉RoutePredicateFactory的字符串也就是Test,路由配置为下面
#自定义断言
spring.cloud.gateway.routes[0].predicates[5]=Test=dxg
现在我们测试带个name交xg的,我们配置的是dxg,所以会访问失败
接下来测试dxg,这次应该成功:
自定义断言结束。
接下来看看过滤器
过滤器
定义全局过滤器,需要继承俩个接口GlobalFilter, Ordered,
GlobalFilter是具体过滤逻辑,Ordered是定义过滤器的顺序,就是说可以定义多个过滤器,这个用来指定过滤器的执行顺序。
package com.gateway.filters;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
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.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
/**
* @author xg
*/
@Component
public class TestFilter implements GlobalFilter, Ordered {
/**
* 过滤器的具体逻辑
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String token = request.getQueryParams().getFirst("token");
// 判断token是否符合条件,正确则进入接口调用流程。否则不合法请求,直接返回
if(StringUtils.isNotEmpty(token)) {
// token的具体判断逻辑
if("1q2w3e4r".equals(token)) {
// 校验通过,走接下来接口逻辑或者其他过滤器
return chain.filter(exchange);
}
}
// 不合法token,直接返回,提示没有权限
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
DataBuffer buffer = response.bufferFactory().wrap(JSONObject.toJSONString("token is illegal.").getBytes(StandardCharsets.UTF_8));
return response.writeWith(Flux.just(buffer));
}
/**
* 用来定义过滤器的执行顺序,升序执行
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
我们定义的过滤器必须携带token,而且必须符合我们定义的规则才可通过,否则属于不合法的请求,不允许访问。
我们随便携带了token,不符合条件来访问试试:
http://10.45.12.63:8099/provider-route/provider/get?name=dxg&token=1234
直接报token不合法,接下来我们试试合法的token
http://10.45.12.63:8099/provider-route/provider/get?name=dxg&token=1q2w3e4r
请求成功,到此,我们的过滤器就创建成功了。当然我们的逻辑很是简单,真正的过滤器可以做很多功能,token鉴权,日志打印等等。有兴趣可以自己去试试。如果觉得不错,希望大家点赞加关注哦。
- 事物的精粹,总在它离去时方才显现
- 愿大家珍惜所拥有的,不负韶华,以梦为马,历尽千帆,归来仍是少年。
相关推荐
- Qwen上新AI前端工程师!一句话搞定HTML/CSS/JS,秒变React大神
-
梦晨发自凹非寺量子位|公众号QbitAIQwen上新“AI前端工程师”WebDev,一句话开发网页应用。三大件HTML,CSS,JavaScript一个工具全包了,定睛一看用的还是Reac...
- 程序员的 JavaScript 代码该如何让计算机搞懂?
-
出自程序员之手的JavaScript代码,该如何变成计算机所能理解的机器语言呢?本文将带你走进JavaScript引擎内部,一探究竟。作者|LydiaHallie译者|弯月,责编|...
- JavaScript:如何优雅的创建数组?
-
在JavaScript里,有多种方式可以创建数组,下面为你详细介绍:1.使用数组字面量这是最常用的创建数组的方法,使用方括号[]来创建数组。//创建一个空数组letemptyArray...
- Jquery 详细用法
-
1、jQuery介绍(1)jQuery是什么?是一个js框架,其主要思想是利用jQuery提供的选择器查找要操作的节点,然后将找到的节点封装成一个jQuery对象。封装成jQuery对象的目的有...
- HTML页面基本结构和加载过程
-
大家好,我是皮皮。前言对于前端来说,HTML都是最基础的内容。今天,我们来了解一下HTML和网页有什么关系,以及与DOM有什么不同。通过本讲内容,你将掌握浏览器是怎么处理HTML内容的,...
- 【HarmonyOS Next之旅】兼容JS的类Web开发(一)
-
目录1->概述1.1->整体架构2->文件组织2.1->目录结构2.2->文件访问规则2.3->媒体文件格式3->js标签配置3....
- JavaScript初学者指南
-
如果你刚接触JavaScript,想必已经被“modulebundlersvs.moduleloaders”、“Webpackvs.Browserify”和“AMDvs.Common...
- 前端图片延迟加载详细讲解
-
原文链接:http://www.gbtags.com/gb/share/6366.htm?原本是打算昨天昨天下午的时候就写一篇关于前端图片延迟加载的详细技术的博客的,没想到下午公司项目出现了一些问题...
- selenium:操作滚动条的方法(8)
-
selenium支持几种操作滚动条的方法,主要介绍如下:使用ActionChains类模拟鼠标滚轮操作使用函数ActionChains.send_keys发送按键Keys.PAGE_DOWN往下滑动...
- jQuery 获取和设置HTML元素
-
jQuery中包含更改和操作HTML元素和属性的强大方法。我们可以通过这些方法来获取HTML元素中的文本内容、元素内容(例如HTML标签)、属性值等。text()方法text()方法可以用...
- JavaScript脚本如何断言select下拉框的元素内容?
-
使用JavaScript脚本断言select下拉框的元素内容,需要考虑页面元素是否加载成功,出错时打印等,主要实现功能功能需包括如下几点:1.等待下拉框元素加载完成(支持超时设置)2.获取下...
- JavaScript图片或者div拖动拖动函数的实现
-
/**拖动图片封装html格式:<imglay-src="${item.Resourcesurl}"alt="${item.ResourcesName}"...
- JavaScript代码怎样引入到HTML中?
-
JavaScript程序不能独立运行,它需要被嵌入HTML中,然后浏览器才能执行JavaScript代码。通过<script>标签将JavaScript代码引入到HTM...
- 当你在Vue.js中想要隐藏 `` 标签时,可以这样做:
-
在Vue.js里,要是你想要搞掉`<br>`(换行)标签的效果,通常有几种路子:1.使用CSS嗯,最简单的办法就是用CSS搞定,控制元素的样式,让<br>标签彻底不显示...
- php手把手教你做网站(三十)上传图片生成缩略图
-
三种方法:按比例缩小、图片裁切、预览图片裁切不管使用哪一个都是建立在图片已经上传的基础上;预览裁切上传,如果预览的图片就是原始大小,可以预览裁切以后上传(这里是个假象,下边会说明);1、上传以后按比例...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)