如何在Spring Gateway中获取响应主体

huangapple go评论115阅读模式
英文:

How to get response body in Spring Gateway

问题

  1. 我正在使用Spring Cloud Gateway过滤器,并且需要获取响应体以进行日志记录。
  2. 我理解这可能有问题,因为Spring Gateway是构建在Spring Reactor上的,但尽管如此,我仍在寻找任何方法来实现这一点。
  3. 有一个全局过滤器,代码如下:
  4. import org.reactivestreams.Publisher;
  5. import org.reactivestreams.Subscriber;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.cloud.gateway.filter.GatewayFilter;
  8. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
  9. import org.springframework.cloud.gateway.filter.GlobalFilter;
  10. import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
  11. import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
  12. import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
  13. import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
  14. import org.springframework.core.Ordered;
  15. import org.springframework.stereotype.Component;
  16. import org.springframework.web.server.ServerWebExchange;
  17. import reactor.core.publisher.Mono;
  18. @Component
  19. public class BodyRewrite implements RewriteFunction<byte[], byte[]> {
  20. @Override
  21. public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
  22. System.out.println("-------------------------");
  23. System.out.println(" APPLY METHOD");
  24. System.out.println("-------------------------");
  25. String originalBody = body == null ? "" : new String(body);
  26. if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
  27. return Mono.just(originalBody.getBytes());
  28. } else {
  29. System.out.println("RESPONSE: " + originalBody);
  30. }
  31. return new Publisher<byte[]>() {
  32. @Override
  33. public void subscribe(Subscriber<? super byte[]> subscriber) {
  34. }
  35. };
  36. }
  37. }
  38. @Component
  39. class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
  40. @Autowired
  41. private ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
  42. @Autowired
  43. private BodyRewrite bodyRewrite;
  44. @Override
  45. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  46. System.out.println("---------------------------");
  47. System.out.println(" GLOBAL FILTER");
  48. System.out.println("---------------------------");
  49. GatewayFilter delegate = modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
  50. .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
  51. return delegate.filter(exchange, chain);
  52. }
  53. @Override
  54. public int getOrder() {
  55. return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
  56. }
  57. }

在控制台中,我只会连续看到大约30次的以下输出,并且没有带有“APPLY METHOD”短语的输出。

  1. ---------------------------
  2. GLOBAL FILTER
  3. ---------------------------
英文:

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:

  1. import org.reactivestreams.Publisher;
  2. import org.reactivestreams.Subscriber;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.cloud.gateway.filter.GatewayFilter;
  5. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
  6. import org.springframework.cloud.gateway.filter.GlobalFilter;
  7. import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
  8. import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
  9. import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
  10. import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
  11. import org.springframework.core.Ordered;
  12. import org.springframework.stereotype.Component;
  13. import org.springframework.web.server.ServerWebExchange;
  14. import reactor.core.publisher.Mono;
  15. @Component
  16. public class BodyRewrite implements RewriteFunction&lt;byte[], byte[]&gt; {
  17. @Override
  18. public Publisher&lt;byte[]&gt; apply(ServerWebExchange exchange, byte[] body) {
  19. System.out.println(&quot;-------------------------&quot;);
  20. System.out.println(&quot; APPLY METHOD&quot;);
  21. System.out.println(&quot;-------------------------&quot;);
  22. String originalBody = body==null?&quot;&quot;:new String(body);
  23. if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
  24. return Mono.just(originalBody.getBytes());
  25. } else {
  26. System.out.println(&quot;RESPONSE: &quot; + originalBody);
  27. }
  28. return new Publisher&lt;byte[]&gt;() {
  29. @Override
  30. public void subscribe(Subscriber&lt;? super byte[]&gt; subscriber) {
  31. }
  32. };
  33. }
  34. }
  35. @Component
  36. class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
  37. @Autowired
  38. private ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
  39. @Autowired
  40. private BodyRewrite bodyRewrite;
  41. @Override
  42. public Mono&lt;Void&gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  43. System.out.println(&quot;---------------------------&quot;);
  44. System.out.println(&quot; GLOBAL FILTER&quot;);
  45. System.out.println(&quot;---------------------------&quot;);
  46. GatewayFilter delegate=modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
  47. .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
  48. return delegate.filter(exchange, chain);
  49. }
  50. @Override
  51. public int getOrder() {
  52. return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1;
  53. }

In the console I only get this output about 30 times in a row and no output with phrase "APPLY METHOD".

  1. ---------------------------
  2. GLOBAL FILTER
  3. ---------------------------

答案1

得分: 1

  1. 我是一个新手无论是在英语还是编程方面
  2. 这里有一种方法但可能不太优雅
  3. 使用ModifyResponseBodyGatewayFilterFactory创建一个modifyResponseBodyFilter并实现RewriteFunction
  4. public class BodyRewrite implements RewriteFunction<byte[], byte[]> {
  5. @Override
  6. public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
  7. String originalBody = body == null ? "" : new String(body);
  8. if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
  9. return Mono.just(originalBody.getBytes());
  10. } else {
  11. // 当已经路由时,它是响应体
  12. }
  13. }
  14. }
  15. public class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
  16. @Autowired
  17. private ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
  18. @Autowired
  19. private BodyRewrite bodyRewrite;
  20. @Override
  21. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  22. GatewayFilter delegate = modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
  23. .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
  24. return delegate.filter(exchange, chain);
  25. }
  26. @Override
  27. public int getOrder() {
  28. return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
  29. }
  30. }
英文:

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.

  1. public class BodyRewrite implements RewriteFunction&lt;byte[], byte[]&gt; {
  2. @Override
  3. public Publisher&lt;byte[]&gt; apply(ServerWebExchange exchange, byte[] body) {
  4. String originalBody = body==null?&quot;&quot;:new String(body);
  5. if (!ServerWebExchangeUtils.isAlreadyRouted(exchange)) {
  6. return Mono.just(originalBody.getBytes());
  7. } else {
  8. // its the reponse body when already routed
  9. }
  10. }
  11. }
  12. public class ModifyResponseBodyFilter implements GlobalFilter, Ordered {
  13. @Autowired
  14. private ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory;
  15. @Autowired
  16. private BodyRewrite bodyRewrite;
  17. @Override
  18. public Mono&lt;Void&gt; filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  19. GatewayFilter delegate=modifyResponseBodyGatewayFilterFactory.apply(new ModifyResponseBodyGatewayFilterFactory.Config()
  20. .setRewriteFunction(byte[].class, byte[].class, bodyRewrite));
  21. return delegate.filter(exchange, chain);
  22. }
  23. @Override
  24. public int getOrder() {
  25. return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER-1;
  26. }
  27. }

huangapple
  • 本文由 发表于 2020年10月20日 13:40:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64439102.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定