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

mpbci0fu  于 2024-01-06  发布在  Spring
关注(0)|答案(1)|浏览(131)

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

  1. @Component
  2. public class EncryptionFilter implements WebFilter {
  3. @Override
  4. public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
  5. Decorator decorator = new Decorator(exchange.getResponse());
  6. return chain.filter(exchange.mutate().response(decorator).build());
  7. }
  8. public class Decorator extends ServerHttpResponseDecorator {
  9. public Decorator(ServerHttpResponse delegate) {
  10. super(delegate);
  11. }
  12. @Override
  13. public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
  14. Mono<DataBuffer> modifiedBody = Mono.from(body)
  15. .map(dataBuffer -> {
  16. byte[] content = new byte[dataBuffer.readableByteCount()];
  17. dataBuffer.read(content);
  18. String originalContent = new String(content, StandardCharsets.UTF_8);
  19. String modifiedContent = originalContent + " Modified";
  20. return getDelegate().bufferFactory().wrap(modifiedContent.getBytes(StandardCharsets.UTF_8));
  21. });
  22. return super.writeWith(modifiedBody);
  23. }
  24. }
  25. }

字符串
我可以看到我的过滤器被调用,我可以读取原始响应。然而,客户端仍然接收原始响应主体。我的假设是,在我实际修改之前,响应已经写入客户端。
使用@Order注解似乎没有效果,我已经尝试了最低和最高优先级。我还尝试禁用所有其他过滤器,所以这个过滤器是唯一正在执行的过滤器。

vhmi4jdf

vhmi4jdf1#

您还需要重写Content-Length头,如下所示:

  1. @Override
  2. public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
  3. Mono<DataBuffer> modifiedBody = Mono.from(body)
  4. .map(dataBuffer -> {
  5. byte[] content = new byte[dataBuffer.readableByteCount()];
  6. dataBuffer.read(content);
  7. String originalContent = new String(content, StandardCharsets.UTF_8);
  8. String modifiedContent = originalContent + " Modified";
  9. byte[] modifiedContentBytes = modifiedContent.getBytes(StandardCharsets.UTF_8);
  10. getHeaders().setContentLength(modifiedContentBytes.length);
  11. return getDelegate().bufferFactory().wrap(modifiedContentBytes);
  12. });
  13. return super.writeWith(modifiedBody);
  14. }

字符串
这解决了使用以下端点测试的问题:

  1. @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
  2. public Mono<String> test(){
  3. return Mono.just("Test");
  4. }


回应:
测试修改

展开查看全部

相关问题