SpringCloud gateway如何修改返回数据

这篇文章主要介绍了SpringCloud gateway如何修改返回数据的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

版本说明

开源软件

版本

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

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

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类

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 inClass, Class outClass, RewriteFunction rewriteFunction) // inClass 原数据类型,可以指定为具体数据类型,我这里指定为Object,是为了处理多种数据类型。 // 当然支持多接口返回多数据类型的统一修改,yaml中的配置,path,uri需要做相关调整 // outClass 目标数据类型 // rewriteFunction 内容重写方法 cf.setRewriteFunction(Object.class, UnionResult.class, getRewriteFunction()); return cf; } private RewriteFunction 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修改返回的响应体

问题描述:

在gateway中修改返回的响应体,在全局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 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)设置一个响应装饰器(自定义),以下是装饰器具体实现:

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 writeWith(Publisher extends DataBuffer> body) { if(body instanceof Flux) { Flux fluxBody = (Flux) 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(); } }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程之家。

相关文章

Java中的String是不可变对象 在面向对象及函数编程语言中,不...
String, StringBuffer 和 StringBuilder 可变性 String不可变...
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序...
先说结论,是对象!可以继续往下看 数组是不是对象 什么是对...
为什么浮点数 float 或 double 运算的时候会有精度丢失的风险...
面试题引入 这里引申出一个经典问题,看下面代码 Integer a ...