当前位置:   article > 正文

SpringCloud-Gateway修改Response响应体,并解决大数据量返回不全等问题_modifyresponsebodygatewayfilterfactory

modifyresponsebodygatewayfilterfactory

官网相关案例:

Spring Cloud Gatewayicon-default.png?t=N7T8https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-modifyresponsebody-gatewayfilter-factory

ModifyRequestBodyGatewayFilterFactory类:

https://github.com/spring-cloud/spring-cloud-gateway/blob/3.1.x/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.javaicon-default.png?t=N7T8https://github.com/spring-cloud/spring-cloud-gateway/blob/3.1.x/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite/ModifyResponseBodyGatewayFilterFactory.java

相关代码:

  1. import cn.hutool.core.collection.CollUtil;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.alibaba.fastjson.JSONObject;
  4. import lombok.AllArgsConstructor;
  5. import lombok.Data;
  6. import lombok.NoArgsConstructor;
  7. import lombok.SneakyThrows;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.reactivestreams.Publisher;
  10. import org.springframework.cloud.gateway.filter.GatewayFilter;
  11. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
  12. import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
  13. import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
  14. import org.springframework.core.Ordered;
  15. import org.springframework.core.io.buffer.DataBuffer;
  16. import org.springframework.core.io.buffer.DataBufferFactory;
  17. import org.springframework.core.io.buffer.DataBufferUtils;
  18. import org.springframework.core.io.buffer.DefaultDataBufferFactory;
  19. import org.springframework.http.HttpHeaders;
  20. import org.springframework.http.HttpStatus;
  21. import org.springframework.http.MediaType;
  22. import org.springframework.http.server.reactive.ServerHttpResponse;
  23. import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
  24. import org.springframework.stereotype.Component;
  25. import org.springframework.web.server.ServerWebExchange;
  26. import reactor.core.publisher.Flux;
  27. import reactor.core.publisher.Mono;
  28. import java.util.List;
  29. /**
  30. * @Author: meng
  31. * @Description: 自定义返回体 - 借鉴原生类ModifyRequestBodyGatewayFilterFactory实现
  32. * https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the
  33. * -modifyresponsebody-gatewayfilter-factory
  34. * @Date: 2023/4/18 13:37
  35. * @Version: 1.0
  36. */
  37. @Slf4j
  38. @Component
  39. public class ResponseGatewayFilterFactory extends AbstractGatewayFilterFactory<ResponseGatewayFilterFactory.Config> {
  40. public ResponseGatewayFilterFactory() {
  41. super(Config.class);
  42. }
  43. @Data
  44. @AllArgsConstructor
  45. @NoArgsConstructor
  46. public static class Config {
  47. // 不需要自定义的接口
  48. List<String> pathExclude;
  49. }
  50. @Override
  51. public GatewayFilter apply(Config config) {
  52. RewriteResponseGatewayFilter rewriteResponseGatewayFilter = new RewriteResponseGatewayFilter(config);
  53. return rewriteResponseGatewayFilter;
  54. }
  55. public class RewriteResponseGatewayFilter implements GatewayFilter, Ordered {
  56. private Config config;
  57. public RewriteResponseGatewayFilter(Config config) {
  58. this.config = config;
  59. }
  60. @Override
  61. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  62. // 不需要自定义的接口,直接返回
  63. log.info("pathExclude:{}", config.pathExclude);
  64. if (CollUtil.isNotEmpty(config.pathExclude)) {
  65. long count = config.pathExclude.stream()
  66. .filter(uri -> StrUtil.contains(exchange.getRequest().getPath().toString(), uri))
  67. .count();
  68. if (count > 0) {
  69. return chain.filter(exchange);
  70. }
  71. }
  72. String appId = exchange.getRequest().getHeaders().getFirst("X-APPID");
  73. if (StrUtil.isBlank(appId)) {
  74. return buildResponse(exchange, HttpStatus.UNAUTHORIZED.value(), "appId不能为空");
  75. }
  76. ServerHttpResponse originalResponse = exchange.getResponse();
  77. DataBufferFactory bufferFactory = originalResponse.bufferFactory();
  78. try {
  79. ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
  80. @Override
  81. public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
  82. if (body instanceof Flux) {
  83. Flux<? extends DataBuffer> fluxBody = Flux.from(body);
  84. return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
  85. byte[] newContent = new byte[0];
  86. try {
  87. DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
  88. DataBuffer join = dataBufferFactory.join(dataBuffers);
  89. byte[] content = new byte[join.readableByteCount()];
  90. join.read(content);
  91. DataBufferUtils.release(join);
  92. // 获取响应数据
  93. String responseStr = new String(content, "UTF-8");
  94. // 修改响应数据
  95. JSONObject jsonObject = new JSONObject();
  96. jsonObject.put("code", HttpStatus.UNAUTHORIZED.value());
  97. jsonObject.put("message", "请求成功");
  98. jsonObject.put("data", responseStr);
  99. String message = jsonObject.toJSONString();
  100. newContent = message.getBytes("UTF-8");
  101. originalResponse.getHeaders().setContentLength(newContent.length);
  102. }
  103. catch (Exception e) {
  104. log.error("appId:{}, responseStr exchange error:{}", appId, e);
  105. throw new RuntimeException(e);
  106. }
  107. return bufferFactory.wrap(newContent);
  108. }));
  109. }
  110. return super.writeWith(body);
  111. }
  112. @Override
  113. public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
  114. return writeWith(Flux.from(body).flatMapSequential(p -> p));
  115. }
  116. };
  117. return chain.filter(exchange.mutate().response(decoratedResponse).build());
  118. }
  119. catch (Exception e) {
  120. log.error("RewriteResponse error:{}", e);
  121. return Mono.error(new Exception("RewriteResponse fail", e));
  122. }
  123. }
  124. @Override
  125. public int getOrder() {
  126. return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 2;
  127. }
  128. }
  129. @SneakyThrows
  130. public static Mono<Void> buildResponse(ServerWebExchange exchange, int code, String message) {
  131. ServerHttpResponse response = exchange.getResponse();
  132. response.setStatusCode(HttpStatus.OK);
  133. response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
  134. JSONObject jsonObject = new JSONObject();
  135. jsonObject.put("code", code);
  136. jsonObject.put("message", message);
  137. jsonObject.put("data", "");
  138. byte[] bytes = jsonObject.toJSONString().getBytes("UTF-8");
  139. DataBuffer bodyDataBuffer = response.bufferFactory().wrap(bytes);
  140. return response.writeWith(Mono.just(bodyDataBuffer));
  141. }
  142. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/475411
推荐阅读
相关标签
  

闽ICP备14008679号