java - 如何在 Spring Gateway 中获取响应正文
问题描述
我正在使用 spring 云网关过滤器,需要获取响应正文来记录它。我知道这是有问题的,因为弹簧网关是建立在弹簧反应器上的,但是我正在寻找任何方法来做到这一点。
有全局过滤器,代码:
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class BodyRewrite implements RewriteFunction<byte[], byte[]> {
@Override
public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
System.out.println("-------------------------");
System.out.println(" APPLY METHOD");
System.out.println("-------------------------");
String originalBody = body==null?"":new String(body);
if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
return Mono.just(originalBody.getBytes());
} else {
System.out.println("RESPONSE: " + originalBody);
}
return new Publisher<byte[]>() {
@Override
public void subscribe(Subscriber<? super byte[]> subscriber) {
}
};
}
}
@Component
class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
@Autowired
private ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
@Autowired
private BodyRewrite bodyRewrite;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("---------------------------");
System.out.println(" GLOBAL FILTER");
System.out.println("---------------------------");
GatewayFilter delegate=modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
.setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
return delegate.filter(exchange, chain);
}
@Override
public int getOrder() {
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1;
}
在控制台中,我只连续获得大约 30 次此输出,并且没有带有短语“APPLY METHOD”的输出。
---------------------------
GLOBAL FILTER
---------------------------
解决方案
我是一个菜鸟,英语和编程。这是一种方法,但可能并不优雅:使用 ModifyResponseBodyGatewayFilterFactory 创建一个 modifyResponseBodyFilter,并实现 RewriteFunction。
public class BodyRewrite implements RewriteFunction<byte[], byte[]> {
@Override
public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
String originalBody = body==null?"":new String(body);
if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
return Mono.just(originalBody.getBytes());
} else {
// its the reponse body when already routed
}
}
}
public class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
@Autowired
private ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
@Autowired
private BodyRewrite bodyRewrite;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
GatewayFilter delegate=modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
.setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
return delegate.filter(exchange, chain);
}
@Override
public int getOrder() {
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1;
}
}
推荐阅读
- javascript - 为什么后退按钮会破坏我的 React 应用程序的某些部分?
- applescript - AppleScript 无法保存文本编辑文件
- python - 如何根据 Python 中的条件/断点从另一个列表中创建多个列表?
- amazon-web-services - 如何使用弹性 beantalk 和 aws 修复 Flask 应用程序中的内部服务器错误
- php - Codeignater,数据库中的数据全部为空
- excel - VBA 在选择中使用活动行号
- asp.net-mvc-4 - 使用模型重定向到响应视图不会保留模型属性
- python - 检查目标时出错:conv2d_transpose 的预期形状
- ios - 弹出广告有效,但一旦我实施应用内购买将其删除?
- javascript - 根据nodejs中的另一个下拉菜单动态选择下拉菜单