Java 如何在SpringGateway中获取响应体

Java 如何在SpringGateway中获取响应体,java,spring,spring-cloud-gateway,Java,Spring,Spring Cloud Gateway,我正在使用SpringCloudGateway过滤器,需要让响应主体记录它。 我知道这是有问题的,因为SpringGateway是建立在SpringReactor上的,但我仍在寻找实现这一点的方法 具有全局筛选器,代码: import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; import org.springframework.beans.factory.annotation.Autowired

我正在使用SpringCloudGateway过滤器,需要让响应主体记录它。 我知道这是有问题的,因为SpringGateway是建立在SpringReactor上的,但我仍在寻找实现这一点的方法

具有全局筛选器,代码:


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;
    }


我是一名英语和编程新手。 这里有一种方法,但可能并不优雅: 使用ModifyResponseBodyGatewayFilterFactory创建modifyResponseBodyFilter,并实现重写功能

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;
    }
}
public类BodyRewrite实现了rewrite函数{
@凌驾
公共发布服务器应用(ServerWebExchange,字节[]正文){
字符串originalBody=body==null?“:新字符串(body);
如果(!ServerWebExchangeUtils.isAlreadyRouted(交换)){
返回Mono.just(originalBody.getBytes());
}否则{
//它是已经路由的响应体
}
}
}
公共类ModifyResponseBodyFilter实现GlobalFilter,已订购{
@自动连线
私有ModifyResponseBodyGatewayFilterFactory ModifyResponseBodyGatewayFilterFactory;
@自动连线
私人身体重写身体重写;
@凌驾
公共Mono筛选器(服务器WebExchange exchange、网关筛选器链){
GatewayFilter委托=modifyResponseBodyGatewayFilterFactory.apply(新建modifyResponseBodyGatewayFilterFactory.Config())
.setrewrite函数(字节[].class,字节[].class,bodyRewrite));
返回委托。过滤器(交换、链);
}
@凌驾
public int getOrder(){
返回NettyWriteResponseFilter.WRITE\u RESPONSE\u FILTER\u ORDER-1;
}
}

我应该在apply方法的else子句中写什么?你可以只记录'originalBody'有错误“应用程序上下文中某些bean的依赖项形成一个循环:”我在description中添加了图片。对不起,我在中国看不到ht图片。你能粘贴你的代码吗,我上面粘贴的代码在测试后是可以的。您可以尝试弄清楚依赖项之间的关系。我修复了错误,它没有调用apply方法,因此没有得到响应体,是我做错了什么,还是您没有尝试此代码?
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;
    }
}