SpringCloud gateway如何修改返回数据

网友投稿 312 2023-01-01

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.shttp://pringcloudgateway.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.sthttp://ereotype.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")

publpSNRDQLlPzic 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();

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:网站api接口对接小程序(api接口对接小程序需要多久)
下一篇:基于HttpClient上传文件中文名乱码的解决
相关文章

 发表评论

暂时没有评论,来抢沙发吧~