Last active
January 14, 2023 18:17
-
-
Save cer/04ce15ba46f54634312740135fcfdeea to your computer and use it in GitHub Desktop.
Spring Webflux-based proxying controller
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
import org.springframework.core.io.buffer.DefaultDataBufferFactory; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.server.reactive.ServerHttpRequest; | |
import org.springframework.http.server.reactive.ServerHttpResponse; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.util.Assert; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RequestMethod; | |
import org.springframework.web.bind.annotation.ResponseBody; | |
import org.springframework.web.reactive.function.client.WebClient; | |
import reactor.core.publisher.Mono; | |
@Controller | |
public class DefaultController { | |
private DefaultDataBufferFactory defaultDataBufferFactory = new DefaultDataBufferFactory(); | |
@RequestMapping(value = "/api/**", method = RequestMethod.GET) | |
@ResponseBody | |
public Mono<Void> defaultGetHandler(ServerHttpRequest serverRequest, ServerHttpResponse serverHttpResponse) { | |
WebClient client = WebClient.create("http://example.com"); | |
String path = serverRequest.getPath().value(); | |
System.out.println("Path=" + path); | |
// Note http://example.com/api/... returns a badly formatted content header | |
return client.get() | |
.uri("/foo/" + path) | |
.accept(serverRequest.getHeaders().getAccept().toArray(new MediaType[0])) | |
.exchange() | |
.flatMap(clientResponse -> { | |
Assert.isTrue(serverHttpResponse.setStatusCode(clientResponse.statusCode())); | |
serverHttpResponse.getHeaders().addAll(clientResponse.headers().asHttpHeaders()); | |
return serverHttpResponse.writeWith(clientResponse.bodyToFlux(String.class).map(s -> defaultDataBufferFactory.wrap(s.getBytes()))); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi there!
Your solution does not handle non-text responses correctly, e.g. when the proxied server responds with some PDF document.
I assume the following (using Kotlin, excuse me!) code snippet works better (and provides better performance probably):
The idea is to use a
BodyExtractor
to directly accessReactiveHttpInputMessage#getBody
(which returnsFlux<DataBuffer>
).Best regards,
Justus