Created
November 21, 2017 12:55
-
-
Save WeirdBob/b25569d461f0f54444d2c0eab51f3c48 to your computer and use it in GitHub Desktop.
Spring cloud gateway response body modification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
spring: | |
cloud: | |
gateway: | |
routes: | |
- id: test | |
uri: https://httpbin.org:443 | |
predicates: | |
- Path=/uuid | |
- Method=GET | |
server: | |
port: 8080 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package examples; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
@SpringBootApplication | |
@EnableAutoConfiguration | |
public class GatewayApplication { | |
public static void main(String[] args) { | |
SpringApplication.run(GatewayApplication.class, args); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>examples</groupId> | |
<artifactId>gateway</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
<parent> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-parent</artifactId> | |
<version>2.0.0.M5</version> | |
<relativePath /> <!-- lookup parent from repository --> | |
</parent> | |
<properties> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |
<java.version>1.8</java.version> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>org.springframework.cloud</groupId> | |
<artifactId>spring-cloud-starter-gateway</artifactId> | |
<version>2.0.0.M3</version> | |
</dependency> | |
</dependencies> | |
<profiles> | |
<profile> | |
<id>spring</id> | |
<activation> | |
<activeByDefault>true</activeByDefault> | |
</activation> | |
<repositories> | |
<repository> | |
<id>spring-milestones</id> | |
<name>Spring Milestones</name> | |
<url>https://repo.spring.io/libs-milestone-local</url> | |
<snapshots> | |
<enabled>false</enabled> | |
</snapshots> | |
</repository> | |
</repositories> | |
</profile> | |
</profiles> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package examples; | |
import java.nio.charset.Charset; | |
import org.reactivestreams.Publisher; | |
import org.springframework.cloud.gateway.filter.GatewayFilterChain; | |
import org.springframework.cloud.gateway.filter.GlobalFilter; | |
import org.springframework.core.Ordered; | |
import org.springframework.core.io.buffer.DataBuffer; | |
import org.springframework.core.io.buffer.DataBufferFactory; | |
import org.springframework.http.server.reactive.ServerHttpResponse; | |
import org.springframework.http.server.reactive.ServerHttpResponseDecorator; | |
import org.springframework.stereotype.Component; | |
import org.springframework.web.server.ServerWebExchange; | |
import reactor.core.publisher.Flux; | |
import reactor.core.publisher.Mono; | |
@Component | |
public class ToUppercaseGlobalFilter implements GlobalFilter, Ordered { | |
@Override | |
public int getOrder() { | |
return -2; // -1 is response write filter, must be called before that | |
} | |
@Override | |
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { | |
ServerHttpResponse originalResponse = exchange.getResponse(); | |
DataBufferFactory bufferFactory = originalResponse.bufferFactory(); | |
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { | |
@Override | |
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) { | |
if (body instanceof Flux) { | |
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body; | |
return super.writeWith(fluxBody.map(dataBuffer -> { | |
// probably should reuse buffers | |
byte[] content = new byte[dataBuffer.readableByteCount()]; | |
dataBuffer.read(content); | |
byte[] uppedContent = new String(content, Charset.forName("UTF-8")).toUpperCase().getBytes(); | |
return bufferFactory.wrap(uppedContent); | |
})); | |
} | |
return super.writeWith(body); // if body is not a flux. never got there. | |
} | |
}; | |
return chain.filter(exchange.mutate().response(decoratedResponse).build()); // replace response with decorator | |
} | |
} |
https://gist.github.com/MdShohanurRahman/0d27148e7a1c9e05f6542f11c2ad98a0
here is the complete request and response log. You can follow.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thanks for this gist. it steered me towards what i need to modify the response of a body via Spring Cloud Gateway. A lot can be learned from the source code of
ModifyResponseBodyGatewayFilterFactory.java
to maybe improve on this but for my purpose the gist works as it is.edit: oof. that didn't last long 😝. the above approach will work to some degree but it is limited...like, for example, if you intend to modify a JSON response body prior to returning to the client, the above gist will not work (i know because i tried). also note that the gist doesn't take the decoders into account from upstream like here.
I found an article that tackled this and the solution seems to be a modification of
ModifyResponseBodyGatewayFilterFactory
.edit 2: after tinkering around, i was able to write a quick and dirty custom filter that modifies response body based on what
ModifyResponseBodyGatewayFilterFactory
does today ...i wrote up a gist here.