版本说明
开源软件 | 版本 |
---|---|
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