Spring webflux:如何配置Controller和WebClient像代理一样工作?
Spring webflux: how to configure Controller and WebClient to work like proxy?
我需要一个可以在代理模式下工作的端点:将请求转发到外部 REST API。
目前我实现了这样的 class 但它离理想还很远。
import java.net.URI;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
@RestController
public class ProxyController2 {
private static final int OFFSET = 4;
private static final String SCHEME = "http";
private static final String HOTS = "127.0.0.1";
private static final String PORT = "9090";
@RequestMapping("/proxy/public/**")
public Mono<String> publicProxy(ServerHttpRequest request) {
HttpMethod httpMethod = request.getMethod();
if (bodyRequired(httpMethod)) {
return WebClient.create()
.method(httpMethod)
.uri(composeTargetUri(request))
.headers(headers -> headers.addAll(request.getHeaders()))
.body(BodyInserters.fromDataBuffers(request.getBody()))
.retrieve()
.bodyToMono(String.class);
} else {
return WebClient.create()
.method(httpMethod)
.uri(composeTargetUri(request))
.headers(headers -> headers.addAll(request.getHeaders()))
.retrieve()
.bodyToMono(String.class);
}
}
private URI composeTargetUri(ServerHttpRequest request) {
return UriComponentsBuilder.newInstance()
.scheme(SCHEME)
.host(HOTS)
.port(PORT)
.path(getTargetPath(request))
.build()
.toUri();
}
private String getTargetPath(ServerHttpRequest request) {
return request.getPath().pathWithinApplication()
.subPath(OFFSET)
.value();
}
private boolean bodyRequired(HttpMethod httpMethod) {
return httpMethod == HttpMethod.DELETE || httpMethod == HttpMethod.POST
|| httpMethod == HttpMethod.PUT;
}
}
它有一些缺点:
* 它总是 returns 结果为字符串。
* 我们失去回应 headers.
* 我们失去响应状态(它产生 500 错误消息描述)。
你知道在spring webflux 应用程序中创建代理控制器的好方法吗?
Spring 云网关
An API Gateway built on top of the Spring Ecosystem, including: Spring 5, Spring Boot 2 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.
我需要一个可以在代理模式下工作的端点:将请求转发到外部 REST API。 目前我实现了这样的 class 但它离理想还很远。
import java.net.URI;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
@RestController
public class ProxyController2 {
private static final int OFFSET = 4;
private static final String SCHEME = "http";
private static final String HOTS = "127.0.0.1";
private static final String PORT = "9090";
@RequestMapping("/proxy/public/**")
public Mono<String> publicProxy(ServerHttpRequest request) {
HttpMethod httpMethod = request.getMethod();
if (bodyRequired(httpMethod)) {
return WebClient.create()
.method(httpMethod)
.uri(composeTargetUri(request))
.headers(headers -> headers.addAll(request.getHeaders()))
.body(BodyInserters.fromDataBuffers(request.getBody()))
.retrieve()
.bodyToMono(String.class);
} else {
return WebClient.create()
.method(httpMethod)
.uri(composeTargetUri(request))
.headers(headers -> headers.addAll(request.getHeaders()))
.retrieve()
.bodyToMono(String.class);
}
}
private URI composeTargetUri(ServerHttpRequest request) {
return UriComponentsBuilder.newInstance()
.scheme(SCHEME)
.host(HOTS)
.port(PORT)
.path(getTargetPath(request))
.build()
.toUri();
}
private String getTargetPath(ServerHttpRequest request) {
return request.getPath().pathWithinApplication()
.subPath(OFFSET)
.value();
}
private boolean bodyRequired(HttpMethod httpMethod) {
return httpMethod == HttpMethod.DELETE || httpMethod == HttpMethod.POST
|| httpMethod == HttpMethod.PUT;
}
}
它有一些缺点:
* 它总是 returns 结果为字符串。
* 我们失去回应 headers.
* 我们失去响应状态(它产生 500 错误消息描述)。
你知道在spring webflux 应用程序中创建代理控制器的好方法吗?
Spring 云网关
An API Gateway built on top of the Spring Ecosystem, including: Spring 5, Spring Boot 2 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.