SpringCloud gateway如何修改返回数据

 更新时间:2021年06月30日 17:14:47   作者:buddie  
这篇文章主要介绍了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<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

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<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)设置一个响应装饰器(自定义),以下是装饰器具体实现:

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

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

相关文章

  • 使用Java接收和处理OpenTelemetry数据的完整指南

    使用Java接收和处理OpenTelemetry数据的完整指南

    在现代分布式系统中,OpenTelemetry 成为了一种常见的标准,用于跟踪和监控应用程序的性能和行为,OTLP是 OpenTelemetry 社区定义的一种数据传输协议,文将介绍如何使用 Java 编写代码来接收和处理 OTLP 数据,需要的朋友可以参考下
    2024-04-04
  • 原生Java操作mysql数据库过程解析

    原生Java操作mysql数据库过程解析

    这篇文章主要介绍了原生Java操作mysql数据库过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Spark网站日志过滤分析实例讲解

    Spark网站日志过滤分析实例讲解

    这篇文章主要介绍了Spark网站日志过滤分析实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-02-02
  • Java 并发编程:volatile的使用及其原理解析

    Java 并发编程:volatile的使用及其原理解析

    下面小编就为大家带来一篇Java 并发编程:volatile的使用及其原理解析。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • Spring Security之LogoutSuccessHandler注销成功操作方式

    Spring Security之LogoutSuccessHandler注销成功操作方式

    这篇文章主要介绍了Spring Security之LogoutSuccessHandler注销成功操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 使用spring oauth2框架获取当前登录用户信息的实现代码

    使用spring oauth2框架获取当前登录用户信息的实现代码

    这篇文章主要介绍了使用spring oauth2框架获取当前登录用户信息的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • java实现客户信息管理系统

    java实现客户信息管理系统

    这篇文章主要为大家详细介绍了java实现客户信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • 关于使用swagger整合springMVC的方法

    关于使用swagger整合springMVC的方法

    在平时开发写接口文档的工作时,一般都是word文档,带来书写麻烦、维护麻烦的问题,比如改了源代码忘了更新文档、解释不明确带来歧义、无法在线尝试等等,swagger可以有效解决这类问题,需要的朋友可以参考下
    2023-04-04
  • Java8新特性之lambda的作用_动力节点Java学院整理

    Java8新特性之lambda的作用_动力节点Java学院整理

    我们期待了很久lambda为java带来闭包的概念,但是如果我们不在集合中使用它的话,就损失了很大价值。现有接口迁移成为lambda风格的问题已经通过default methods解决了,在这篇文章将深入解析Java集合里面的批量数据操作解开lambda最强作用的神秘面纱。
    2017-06-06
  • 关于maven本地仓库的配置方式

    关于maven本地仓库的配置方式

    这篇文章主要介绍了关于maven本地仓库的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06

最新评论