Spring Cloud Gateway 网关拦截转发
1.application.yml配置
-
spring:
-
cloud:
-
gateway:
-
routes:
-
- id: remoteaddr_route
-
uri: http://localhost:8080
-
predicates:
-
- Path=/test
-
filters:
-
- RewritePath=/test, /add
-
- Test
参数解析:
predicates:当满足predicates下的条件时,即path路径为/test时网关生效。
uri:跳转到uri(注意:此处为uri不是url)。
filters:filters 下的RewritePath会将路径重定义将/test换为/add。若不加此处就会将path所带路径自动拼接到uri后面。
最后一行的- Test 是文件名,下面会写到
2.网关实现
网关的主要实现由Filter,Mono,GatewayFilterFactory三部分组成。
解析:
GatewayFilterFactory:上面的-Test的文件名就是此处的名称应为TestGatewayFilterFactory,网关匹配时会自动忽略后面的GatewayFilterFactory,从而通过Test找到TestGatewayFilterFactory。
-
-
-
-
public class TestGatewayFilterFactory extends AbstractGatewayFilterFactory {
-
-
TestFilter TestFilter;
-
-
-
public GatewayFilter apply(Object config) {
-
return TestFilter;
-
}
-
}
Filter:相当于一个中间层
-
-
public class TestFilter implements GatewayFilter, Ordered {
-
-
TestMono TestMono;
-
-
-
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
-
return TestMono.testMono(exchange, chain);
-
}
-
-
-
public int getOrder() {
-
return -2;
-
}
-
}
Mono:主要的逻辑实现层
主要实现由testMono来协调,网关转发的请求的解析在此方法内实现,若有解密需求在此方法内添加方法即可。
requestDecorator:此方法用于请求的转换,代码中实现的是将post请求转为get。
urlEncodeUTF8:在此代码的实现中用于解析post请求的参数将其拼接到get请求中。
responseDecorator:网关处理完毕后返回的结果将在这里包装后输出,若有加密在此方法内执行。
-
-
-
public class TestMono {
-
-
//主方法
-
public Mono<Void> testMono(ServerWebExchange exchange, GatewayFilterChain chain) {
-
ServerHttpRequest request = exchange.getRequest();
-
ServerHttpResponse response = exchange.getResponse();
-
return DataBufferUtils.join(request.getBody())
-
.flatMap(dataBuffer -> {
-
DataBufferUtils.retain(dataBuffer);
-
byte[] bytes = new byte[dataBuffer.readableByteCount()];
-
dataBuffer.read(bytes);
-
//释放掉内存
-
DataBufferUtils.release(dataBuffer);
-
String body = new String(bytes, StandardCharsets.UTF_8);
-
URI url = request.getURI();
-
log.info("url: {}", url);
-
JSONObject bodyJson = JSON.parseObject(body);
-
JSONObject innerBody = bodyJson.getJSONObject("BODY");
-
-
return chain.filter(exchange.mutate().request(requestDecorator(request, innerBody)).response(responseDecorator(response)).build());
-
});
-
}
-
-
//将post请求转换成get(若是get可连同下面的方法省略)
-
private static ServerHttpRequestDecorator requestDecorator(ServerHttpRequest request, JSONObject body) {
-
return new ServerHttpRequestDecorator(request) {
-
// 重新设置http method
-
-
public HttpMethod getMethod() {
-
return HttpMethod.GET;
-
}
-
-
-
public String getMethodValue() {
-
return "GET";
-
}
-
-
// 转换请求参数
-
-
public URI getURI() {
-
String params = urlEncodeUTF8(body);
-
return URI.create(request.getURI() "?" params);
-
}
-
};
-
}
-
-
/**
-
* 转换urlparam
-
*(post请求忽略)
-
* @param jsonObject
-
* @return
-
*/
-
private static String urlEncodeUTF8(JSONObject jsonObject) {
-
StringBuilder sb = new StringBuilder();
-
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
-
if (sb.length() > 0) {
-
sb.append("&");
-
}
-
sb.append(String.format("%s=%s",
-
entry.getKey(),
-
entry.getValue()
-
));
-
}
-
log.info("format param: {}", sb);
-
return sb.toString();
-
}
-
-
-
//网关转出
-
private ServerHttpResponseDecorator responseDecorator
-
(ServerHttpResponse response) {
-
return new ServerHttpResponseDecorator(response) {
-
-
-
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
-
if (body instanceof Flux) {
-
Flux<? extends DataBuffer> flux = Flux.from(body);
-
return super.writeWith(flux.buffer().map(dataBuffers -> {
-
DataBufferFactory dataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
-
StringBuilder sb = new StringBuilder("");
-
DataBuffer join = dataBufferFactory.join(dataBuffers);
-
byte[] bytes = new byte[join.readableByteCount()];
-
join.read(bytes);
-
DataBufferUtils.release(join);
-
String s = new String(bytes, StandardCharsets.UTF_8);
-
sb.append(s);
-
//去掉字符串最外层的[]
-
//sb.deleteCharAt(0).deleteCharAt(sb.length() - 1);`
-
// 构造返回报文
-
JSONObject jsonBody = JSON.parseObject(sb.toString(), JSONObject.class, Feature.OrderedField);
-
-
-
String content = JSON.toJSONString(jsonBody, SerializerFeature.WRITE_MAP_NULL_FEATURES, SerializerFeature.QuoteFieldNames, SerializerFeature.PrettyFormat);
-
byte[] contentByte = content.getBytes();
-
// 重置content-length
-
response.getHeaders().setContentLength(contentByte.length);
-
return response.bufferFactory().wrap(contentByte);
-
}));
-
}
-
return super.writeWith(body);
-
}
-
};
-
}
-
-
-
}
Spring cloud gateway学习地址:Spring Cloud Gateway 2.1.0 中文官网文档 - 云 社区 - 腾讯云
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfjaefh
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01