英文:
How to get response body in Spring Gateway
问题
我正在使用Spring Cloud Gateway过滤器,并且需要获取响应体以进行日志记录。
我理解这可能有问题,因为Spring Gateway是构建在Spring Reactor上的,但尽管如此,我仍在寻找任何方法来实现这一点。
有一个全局过滤器,代码如下:
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
---------------------------
英文:
I'm working with spring cloud gateway filters and need to get response body to log it.
I understand that it's problematic, as spring gateway is built on spring reactor, but nevertheless I'm looking for any way to do this.
Have global filter, code:
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;
}
In the console I only get this output about 30 times in a row and no output with phrase "APPLY METHOD".
---------------------------
GLOBAL FILTER
---------------------------
答案1
得分: 1
我是一个新手,无论是在英语还是编程方面。
这里有一种方法,但可能不太优雅:
使用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 {
// 当已经路由时,它是响应体
}
}
}
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;
}
}
英文:
im a rookie,both in English and Programing.
here is a way but may not elegant:
create a modifyResponseBodyFilter with the ModifyResponseBodyGatewayFilterFactory, and implement the 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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论