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

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

相关文章

  • 浅析mybatis和spring整合的实现过程

    浅析mybatis和spring整合的实现过程

    据官方的说法,在Mybatis3问世之前,Spring3的开发工作就已经完成了,所以Spring3中还是没有对Mybatis3的支持。因此由Mybatis社区自己开发了一个Mybatis-Spring用来满足Mybatis用户整合Spring的需求,下面通过Mybatis-Spring来整合Mybatis跟Spring的用法做介绍
    2015-10-10
  • Java使用Runnable和Callable实现多线程的区别详解

    Java使用Runnable和Callable实现多线程的区别详解

    这篇文章主要为大家详细介绍了Java使用Runnable和Callable实现多线程的区别之处,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2022-07-07
  • 解决springboot报错找不到自动注入的service问题

    解决springboot报错找不到自动注入的service问题

    这篇文章主要介绍了解决springboot报错找不到自动注入的service问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java 回调函数深入理解

    Java 回调函数深入理解

    这篇文章主要介绍了 Java 回调函数深入理解的相关资料,需要的朋友可以参考下
    2017-03-03
  • Struts2访问Servlet的三种方式

    Struts2访问Servlet的三种方式

    这篇文章主要介绍了Struts2访问Servlet的三种方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 关于在IDEA热部署插件JRebel使用问题详解

    关于在IDEA热部署插件JRebel使用问题详解

    这篇文章主要介绍了关于在IDEA热部署插件JRebel使用问题详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 利用java开发简易版扫雷游戏

    利用java开发简易版扫雷游戏

    这篇文章主要介绍了利用java开发一个丐版扫雷游戏,喜欢玩扫雷的小伙伴们一定要试试哦,对正在学习java开发的小伙伴们也有一定帮助,需要的朋友可以参考下
    2021-04-04
  • java 实现字节流和字节缓冲流读写文件时间对比

    java 实现字节流和字节缓冲流读写文件时间对比

    这篇文章主要介绍了java 实现字节流和字节缓冲流读写文件时间对比,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 基于Java实现XML文件的解析与更新

    基于Java实现XML文件的解析与更新

    配置文件可以有很多种格式,包括 INI、JSON、YAML 和 XML。每一种编程语言解析这些格式的方式都不同。本文将通过Java语言实现XML文件的解析与更新,需要的可以参考一下
    2022-03-03
  • SpringBoot接收参数所有方式总结

    SpringBoot接收参数所有方式总结

    这篇文章主要介绍了SpringBoot接收参数所有方式总结,文中通过代码示例和图文结合的方式给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-07-07

最新评论