SpringCloud gateway如何修改返回?cái)?shù)據(jù)
版本說(shuō)明
| 開源軟件 | 版本 |
|---|---|
| springboot | 2.1.6.RELEASE |
| jdk | 11.0.3 |
gradle
主要引入了springboot 2.1,lombok
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
定義路由及過(guò)濾器 test-route路由,當(dāng)Path為/users時(shí),轉(zhuǎn)到uri中配置的鏈接http://127.0.0.1:8123/users中。使用UnionResult來(lái)過(guò)濾
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”,就是對(duì)應(yīng)的過(guò)濾器Java類
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 原數(shù)據(jù)類型,可以指定為具體數(shù)據(jù)類型,我這里指定為Object,是為了處理多種數(shù)據(jù)類型。
// 當(dāng)然支持多接口返回多數(shù)據(jù)類型的統(tǒng)一修改,yaml中的配置,path,uri需要做相關(guān)調(diào)整
// outClass 目標(biāo)數(shù)據(jù)類型
// rewriteFunction 內(nèi)容重寫方法
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
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修改返回的響應(yīng)體
問(wèn)題描述:
在gateway中修改返回的響應(yīng)體,在全局Filter中添加如下代碼:
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;
}
}
通過(guò).response(decorator)設(shè)置一個(gè)響應(yīng)裝飾器(自定義),以下是裝飾器具體實(shí)現(xiàn):
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 響應(yīng)裝飾器(重構(gòu)響應(yīng)體)
*/
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);// 釋放掉內(nèi)存
String bodyStr = new String(content, Charset.forName("UTF-8")); //修改響應(yīng)體
bodyStr = modifyBody(bodyStr); getDelegate().getHeaders().setContentLength(bodyStr.getBytes().length);
return bufferFactory().wrap(bodyStr.getBytes());
}));
}
return super.writeWith(body);
} //重寫這個(gè)函數(shù)即可
private String modifyBody(String jsonStr){
JSONObject json = new JSONObject(jsonStr);
//TODO...修改響應(yīng)體
return json.toString();
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺析mybatis和spring整合的實(shí)現(xiàn)過(guò)程
據(jù)官方的說(shuō)法,在Mybatis3問(wèn)世之前,Spring3的開發(fā)工作就已經(jīng)完成了,所以Spring3中還是沒(méi)有對(duì)Mybatis3的支持。因此由Mybatis社區(qū)自己開發(fā)了一個(gè)Mybatis-Spring用來(lái)滿足Mybatis用戶整合Spring的需求,下面通過(guò)Mybatis-Spring來(lái)整合Mybatis跟Spring的用法做介紹2015-10-10
Java使用Runnable和Callable實(shí)現(xiàn)多線程的區(qū)別詳解
這篇文章主要為大家詳細(xì)介紹了Java使用Runnable和Callable實(shí)現(xiàn)多線程的區(qū)別之處,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-07-07
解決springboot報(bào)錯(cuò)找不到自動(dòng)注入的service問(wèn)題
這篇文章主要介紹了解決springboot報(bào)錯(cuò)找不到自動(dòng)注入的service問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
關(guān)于在IDEA熱部署插件JRebel使用問(wèn)題詳解
這篇文章主要介紹了關(guān)于在IDEA熱部署插件JRebel使用問(wèn)題詳解,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
java 實(shí)現(xiàn)字節(jié)流和字節(jié)緩沖流讀寫文件時(shí)間對(duì)比
這篇文章主要介紹了java 實(shí)現(xiàn)字節(jié)流和字節(jié)緩沖流讀寫文件時(shí)間對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
基于Java實(shí)現(xiàn)XML文件的解析與更新
配置文件可以有很多種格式,包括?INI、JSON、YAML?和?XML。每一種編程語(yǔ)言解析這些格式的方式都不同。本文將通過(guò)Java語(yǔ)言實(shí)現(xiàn)XML文件的解析與更新,需要的可以參考一下2022-03-03
SpringBoot接收參數(shù)所有方式總結(jié)
這篇文章主要介紹了SpringBoot接收參數(shù)所有方式總結(jié),文中通過(guò)代碼示例和圖文結(jié)合的方式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-07-07

