Spring WebFlux WebFilter:响应体修改没有效果

问题描述 投票:0回答:1

我想修改我的 Spring Boot 应用程序生成的每个响应。为此,我创建了一个如下所示的 WebFilter 组件:

@Component
public class EncryptionFilter implements WebFilter {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    Decorator decorator = new Decorator(exchange.getResponse());
    return chain.filter(exchange.mutate().response(decorator).build());
  }

  public class Decorator extends ServerHttpResponseDecorator {
    public Decorator(ServerHttpResponse delegate) {
      super(delegate);
    }

    @Override
    public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
      Mono<DataBuffer> modifiedBody = Mono.from(body)
          .map(dataBuffer -> {
            byte[] content = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(content);
            String originalContent = new String(content, StandardCharsets.UTF_8);
            String modifiedContent = originalContent + " Modified";
            return getDelegate().bufferFactory().wrap(modifiedContent.getBytes(StandardCharsets.UTF_8));
          });

      return super.writeWith(modifiedBody);
    }
  }
}

我可以看到我的过滤器被调用,并且我可以读取原始响应。但是,客户端仍然收到原始响应正文。我的假设是,在我实际修改响应之前,响应已经写入客户端。

使用

@Order
注释似乎没有效果,我已经尝试了最低和最高优先级。我还尝试禁用所有其他过滤器,因此此过滤器是唯一被执行的过滤器。

spring-boot spring-webflux
1个回答
0
投票

通过使用 WebFilter 来调整响应,您似乎正在朝着正确的方向前进。如果您遇到问题,可能是由于过滤器的执行顺序或响应的处理方式造成的。为了确保您的过滤器在其他过滤器之后运行,请考虑使用 Ordered 接口或 @Order 注释。 以下是如何修改

EncryptionFilter
类以实现
Ordered
的示例:

import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Component
public class EncryptionFilter implements WebFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        Decorator decorator = new Decorator(exchange.getResponse());
        return chain.filter(exchange.mutate().response(decorator).build());
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    public class Decorator extends ServerHttpResponseDecorator {

        public Decorator(ServerHttpResponse delegate) {
            super(delegate);
        }

        @Override
        public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
            Mono<DataBuffer> modifiedBody = Mono.from(body)
                    .map(dataBuffer -> {
                        byte[] content = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(content);
                        String originalContent = new String(content, StandardCharsets.UTF_8);
                        String modifiedContent = originalContent + " Modified";
                        return getDelegate().bufferFactory().wrap(modifiedContent.getBytes(StandardCharsets.UTF_8));
                    });

            return super.writeWith(modifiedBody);
        }
    }
}

通过实现 Ordered 接口并返回 Ordered.HIGHEST_PRECEDENCE,您可以确保您的过滤器在其他过滤器之后运行

© www.soinside.com 2019 - 2024. All rights reserved.