SpringCloud Gateway拦截器遇到的小坑汇总
很多朋友在使用SpringCloudGateway的时候可能都碰到过以下几个问题
SpringCloudGateway中如何读取Post请求体
private BodyInserter getBodyInserter(ServerWebExchange exchange) {
ServerRequest serverRequest = new DefaultServerRequest(exchange);
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class)
.flatMap(body -> {
//这里的body就是Post的请求体
});
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
return bodyInserter;
}
SpringCloudGateway中Post请求参数只能读取一次
这是因为Gateway默认使用的是SpringWebflux,解决这个问题需要容重新构造一个request来替换原先的request
HttpHeaders headers=new HttpHeaders();
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
ServerHttpRequestDecorator decorator = this.getServerHttpRequestDecorator(exchange,outputMessage);
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return outputMessage.getBody();
}
};
当ServerHttpRequestDecorator构建完成之后需要在拦截器中使用如下方法替换原先的request
return chain.filter(exchange.mutate().request(decorator).build());
SpringCloudGateway中如何读取后段服务的返回数据
与上方替换request的思路一致,替换response即可
private ServerHttpResponse getServerHttpResponse(ServerWebExchange exchange) {
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<DataBuffer> flux = null;
if (body instanceof Mono) {
Mono<? extends DataBuffer> mono = (Mono<? extends DataBuffer>) body;
body = mono.flux();
}
if (body instanceof Flux) {
flux = (Flux<DataBuffer>) body;
return super.writeWith(flux.buffer().map(dataBuffers -> {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
dataBuffers.forEach(i -> {
byte[] array = new byte[i.readableByteCount()];
i.read(array);
DataBufferUtils.release(i);
outputStream.write(array, 0, array.length);
});
String result = outputStream.toString();
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
log.info("后端返回数据:{}", result);
return bufferFactory.wrap(result.getBytes());
}));
}
log.info("降级处理返回数据:{}" + body);
return super.writeWith(body);
}
};
return decoratedResponse;
}
上方是获取新的response,获取到新的之后和之前的套路一样,这样操作:
return chain.filter(exchange.mutate().request(decorator).response(decoratedResponse).build());
可能有的同学会碰到即使按照我上述的方法重写了response但是也无法读取到返回数据,这个原因可能是因为拦截器的优先级配置有问题,只需要实现Ordered接口并且重写getOrder方法,然后设置优先级小于-1即可
@Override
public int getOrder() {
return -2;
}
SpringCloud Gateway拦截器遇到的小坑汇总的更多相关文章
- SpringMVC拦截器-路径语法-略坑
项目中遇到一种场景,登录拦截器需要拦截.html后缀等动态请求,但是发现语法不对头. <mvc:interceptors> <mvc:interceptor> ...
- SpringMVC4拦截器配置遇到的坑
目的:对get请求添加token验证(若为post请求可通过RequestBodyAdvice实现). 情景:因为有api版本管理的需求,重写了WebMvcConfigurationSupport类的 ...
- iOS总结:项目中的各种小坑汇总
一.字符串转JSON 在网络请求时,如果服务端返回的是字符串,那么就需要我们自己封装一个类,将请求下来的字符串转换成json对象,从而存入模型中. 注意: 字符串中如果含有一些特殊转意符(如\n.\t ...
- JavaScript中的各种小坑汇总
1.Number()将部分非数字类型转换为0 强制转换为数值类型函数: parseFloat.parseInt 优点:对非数值类型统一返回NaN 缺点:会将一部分符合数值类型的字符串也识别为数值 pa ...
- C++小坑汇总
std::vector::end, 是构想的下一个push_back位置,并不实际指向vector中任何元素. Returns an iterator referring to the past-th ...
- SpringCloud:学习Gateway网关拦截器的ServerWebExchange
1.Gateway的拦截器 我们要在项目中实现一个拦截器,需要继承两个类:GlobalFilter, Ordered GlobalFilter:全局过滤拦截器,在gateway中已经有部分实现,具体参 ...
- 【手记】小心在where中使用NEWID()的大坑 【手记】解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题 【C#】组件分享:FormDragger窗体拖拽器 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed
[手记]小心在where中使用NEWID()的大坑 这个表达式: ABS(CHECKSUM(NEWID())) % 3 --把GUID弄成正整数,然后取模 是随机返回0.1.2这三个数,不可能返回其它 ...
- Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(五):鉴权 gRPC-Interceptor 拦截器实战
拦截器(gRPC-Interceptor)类似于 Gin 中间件(Middleware),让你在真正调用 RPC 服务前,进行身份认证.参数校验.限流等通用操作. 系列 云原生 API 网关,gRPC ...
- SpringMvc拦截器小测试
前言 俗话说做项目是让人成长最快的方案,最近小编写项目的时候遇到了一个小问题.小编在项目中所负责的后台系统,但是后台系统是通过系统的页面是通过ifame联动的,那么这时候问题就来了,后台所做的所有操作 ...
随机推荐
- Angular回顾(1)
一.前端基础 HTML:超文本标记语言,文档排版. DOM:文档对象模型. JS: 脚本语言,解释执行:动态操作DOM,服务器交互,用户交互. CSS:层叠样式表. 二.Angular前提 TypeS ...
- innodb存储引擎监控
innodb存储引擎监控分为四种,表监控,表空间监控,锁监控,状态监控.可以在mysql客户端开启监控选项,然后信息将会输出在mysql的错误日志内.innodb_monitor和innodb_loc ...
- Oracle 11gR2 RAC网络配置,更改public ip、vip和scanip
Oracle 11gR2 RAC网络配置,更改public ip.vip和scanip 转载黑裤子 发布于2018-10-30 01:08:02 阅读数 2898 收藏 展开 转载. https:/ ...
- centos7.6 创建磁盘格式化
fdisk /dev/vdb mkfs.ext4 /dev/vdb echo '/dev/vdb /sdata ext4 defaults 0 0' >> /etc/fstab mount ...
- Mac下编译libpomelo静态库,并在cocos2dx项目中引用
最近在学习cocos2dx的过程中需要和服务器进行交互,所以这几天在学习libpomelo静态库的编译和使用.之前在windows系统下编译libpomelo,并在VS中引入比较顺利:但是,目前对Ma ...
- 《数据挖掘导论》实验课——实验二、数据处理之Matplotlib
实验二.数据处理之Matplotlib 一.实验目的 1. 了解matplotlib库的基本功能 2. 掌握matplotlib库的使用方法 二.实验工具: 1. Anaconda 2. Numpy, ...
- SQL注入神器———Sqlmap!
Sqlmap 开源,python编写 支持5种SQL注入检测技术: 1.基于布尔的注入检测 2.基于时间的注入检测 3.基于错误的注入检测 4.基于UNION联合查询的检测 5.基于堆叠查询的检测 支 ...
- The 2017 ACM-ICPC Asia Shenyang Regional Contest
传送门 F - Heron and His Triangle 直接打表找到规律\(f_i=4f_{i-1}+f_{i-2}\),然后大数预处理一下,对于询问直接输出就行. Code #include ...
- python包matplotlib绘制图像
使用matplotlib绘制图像 import matplotlib.pyplot as plt from matplotlib.pyplot import MultipleLocator impor ...
- BZOJ2339/LG3214 「HNOI2011」 卡农 组合数学
问题描述 BZOJ2339 本题的一些心得 对于这种无序集合计数类问题,可以通过对方案数除以某个数的阶乘,使得无序化变为有序化. 设计DP方程时候,应该先有序的列出状态转移方程每一项的来源,并一项项推 ...