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联动的,那么这时候问题就来了,后台所做的所有操作 ...
随机推荐
- JavaWeb中验证码校验的功能实现
后台生成验证码工具方法 /* * 设置图片的背景色 */ public static void setBackGround(Graphics g, int WIDTH, int HEIGHT) { / ...
- SpringCloud的入门学习之概念理解、Ribbon负载均衡入门
1.Ribbon负载均衡,Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端.负载均衡的工具. 答:简单的说,Ribbon是Netflix发布的开源项目,主要功能 ...
- sql server 2014 卸载
遇到一个沙雕工程人员~二话不装给我装了2014的版本,实际开发的时候用的是2012....欸~ 1.打开服务 2.打开控制面板下的程序与功能 3选中红框点击卸载与更改----->选择删除 4.然 ...
- goweb- 对请求的处理
对请求的处理 Go 语言的 net/http 包提供了一系列用于表示 HTTP 报文的结构,我们可以使用它 处理请求和发送相应,其中 Request 结构代表了客户端发送的请求报文,下面让我们看 一下 ...
- Wappalyzer(chrome网站分析插件)
Wappalyzer是一款功能强大的.且非常实用的chrome网站技术分析插件,通过该插件能够分析目标网站所采用的平台构架. 网站环境.服务器配置环境.JavaScript框架.编程语言等参数,使用时 ...
- SAP 资产相关日期
1. Capitalized Date(资本化日期) 可以手工输入资本化日期,或者如果不输入,则通常默认写入First Acquisition Date (资产第一次购置时输入资产价值日). 2.As ...
- Android Studio添加文件注释头模板集合
Android Studio中设置方式 File -> Settings -> Editor -> File and Code Templates -> 右侧File标签 -& ...
- 移动网络游戏实现流程——并借此阐明pomelo在GitHub上各个项目间的关系
<!DOCTYPE html> 摘要:本文通过一个简易流程图介绍如何基于Cocos2d-x引擎和pomelo服务器框架开发一个移动网络游戏.并借此阐明pomelo提供的各个项目间的关系. ...
- JUC-9-线程按序交替
package com.wf.zhang.juc; import java.util.concurrent.locks.Condition; import java.util.concurrent.l ...
- 给用户提供就医帮助的安卓APP
经过我们的小组的成员讨论,我们确定了我们小组的项目,即是一款给用户提供就医帮助的安卓APP. 项目计划及功能:计划两个月内团队成员共同开发完成此款APP,此款APP提供预约挂号,名医名院咨询, 就医导 ...