gpt4 book ai didi

SpringCloud gateway如何修改返回数据

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 35 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章SpringCloud gateway如何修改返回数据由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

版本说明

开源软件 版本
springboot 2.1.6.RELEASE
jdk 11.0.3

gradle

主要引入了springboot 2.1,lombok 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
plugins {
     id 'org.springframework.boot' version '2.1.6.RELEASE'
     id 'java'
     id "io.freefair.lombok" version "3.6.6"
}apply plugin: 'io.spring.dependency-management' group = 'cn.buddie.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11' repositories {
     mavenCentral()
}ext {
     set( 'springCloudVersion' , "Greenwich.SR2" )
}dependencies {
     implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
     compile 'org.projectlombok:lombok:1.18.8'
     testImplementation 'org.springframework.boot:spring-boot-starter-test'
}dependencyManagement {
     imports {
         mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
     }
}

yaml

定义路由及过滤器 test-route路由,当Path为/users时,转到uri中配置的链接http://127.0.0.1:8123/users中。使用UnionResult来过滤 。

?
1
2
3
4
5
6
7
8
9
10
11
spring:
   cloud:
     gateway:
       enabled: true
       routes:
       - id: test-route
         uri: http://127.0.0.1:8123/users
         predicates:
         - Path=/users
         filters:
         - UnionResult

filter

yaml中配置的filter名字,加“GatewayFilterFactory”,就是对应的过滤器Java类 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package cn.buddie.demo.springcloudgateway.filter; import cn.buddie.demo.springcloudgateway.model.UnionResult;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono; /**
  * description
  *
  * @author buddie.wei
  * @date 2019/7/20
  */
@Component
public class UnionResultGatewayFilterFactory extends ModifyResponseBodyGatewayFilterFactory {
     @Override
     public GatewayFilter apply(Config config) {
         return new ModifyResponseGatewayFilter( this .getConfig());
     }
     private Config getConfig() {
         Config cf = new Config();
         // Config.setRewriteFunction(Class<T> inClass, Class<R> outClass, RewriteFunction<T, R> rewriteFunction)
         // inClass 原数据类型,可以指定为具体数据类型,我这里指定为Object,是为了处理多种数据类型。
         //                      当然支持多接口返回多数据类型的统一修改,yaml中的配置,path,uri需要做相关调整
         // outClass 目标数据类型
         // rewriteFunction 内容重写方法
         cf.setRewriteFunction(Object. class , UnionResult. class , getRewriteFunction());
         return cf;
     }    private RewriteFunction<Object, UnionResult> getRewriteFunction() {
         return (exchange, resp) -> Mono.just(UnionResult.builder().requestId(exchange.getRequest().getHeaders().getFirst( "cn-buddie.demo.requestId" )).result(resp).build());
     }
}

model

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package cn.buddie.demo.springcloudgateway.model; import lombok.Builder;
import lombok.Getter;
import lombok.Setter; /**
  * description
  *
  * @author buddie.wei
  * @date 2019/7/20
  */
@Getter
@Setter
@Builder
public class UnionResult {
     private String requestId;
     private Object result;
}

SpringCloud gateway修改返回的响应体

问题描述:

在gateway中修改返回的响应体,在全局Filter中添加如下代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.springframework.core.Ordered;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; @Component
public class RequestGlobalFilter implements GlobalFilter, Ordered {
  //...
 
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   //...
   ResponseDecorator decorator = new ResponseDecorator(exchange.getResponse());
   return chain.filter(exchange.mutate().response(decorator).build());
  } @Override
  public int getOrder() {
   return - 1000 ;
  }
}

通过.response(decorator)设置一个响应装饰器(自定义),以下是装饰器具体实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import cn.hutool.json.JSONObject;
import org.reactivestreams.Publisher;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.Charset; /**
  * @author visy.wang
  * @desc 响应装饰器(重构响应体)
  */
public class ResponseDecorator extends ServerHttpResponseDecorator{
  public ResponseDecorator(ServerHttpResponse delegate){
   super (delegate);
  } @Override
  @SuppressWarnings (value = "unchecked" )
  public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {  if (body instanceof Flux) {
    Flux<DataBuffer> fluxBody = (Flux<DataBuffer>) body;   return super .writeWith(fluxBody.buffer().map(dataBuffers -> {
     DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
     DataBuffer join = dataBufferFactory.join(dataBuffers);    byte [] content = new byte [join.readableByteCount()];
     join.read(content);
     DataBufferUtils.release(join); // 释放掉内存
    
     String bodyStr = new String(content, Charset.forName( "UTF-8" ));                //修改响应体
     bodyStr = modifyBody(bodyStr);    getDelegate().getHeaders().setContentLength(bodyStr.getBytes().length);
     return bufferFactory().wrap(bodyStr.getBytes());
    }));
   }
   return super .writeWith(body);
  }    //重写这个函数即可
  private String modifyBody(String jsonStr){
   JSONObject json = new JSONObject(jsonStr);
         //TODO...修改响应体
   return json.toString();
  }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.

原文链接:https://my.oschina.net/buddie/blog/3076723 。

最后此篇关于SpringCloud gateway如何修改返回数据的文章就讲到这里了,如果你想了解更多关于SpringCloud gateway如何修改返回数据的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com