我们正在运行一堆微服务,这些微服务由中央网关(org.springframework.cloud:spring-cloud-starter-gateway:2.1.0)保护,该网关将请求路由到背后的负责的微服务。
我们现在要添加一个服务,该服务将通过一个宁静的接口将每个请求的重要部分作为副本(例如标头,请求路径,请求正文...)作为副本进行跟踪/统计。为了只在一个地方使用此代码,我们想将其直接添加到网关服务中。
实施WebFilter似乎是一个不错的开始,但是我在请求正文Flux<DataBuffer>
上遇到了问题。
订阅它会导致错误:Only one connection receive subscriber allowed.
,因为它是单播,禁止内容的多个接收者。
@Slf4j
@Configuration
public class InterceptConfig implements WebFilter {
private final StatisticServiceProperties properties;
@Autowired
public InterceptConfig(StatisticServiceProperties properties) {
this.properties = properties;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
log.debug("request intercepted. sending to statistic service : " + request.getURI().toString());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
request.getBody().subscribe(dataBuffer -> {
try {
byteArrayOutputStream.write(dataBuffer.asInputStream().readAllBytes());
} catch (IOException e) {
log.debug("couldn't extract body from request", e);
}
});
new StatisticServiceClient(
new RestTemplate(),
properties.getBaseUrl() + "/statistic"
).createStatistic(
new CreateStatisticRequest(
new Date(),
request.getURI(),
request.getHeaders(),
byteArrayOutputStream.toByteArray()
)
);
return chain.filter(exchange);
}
}
是否可以在不破坏应用程序的情况下获取请求正文的内容?
编辑:2019年11月18日
我找到了一个可以为我解决此问题的解决方案: https://github.com/spring-cloud/spring-cloud-gateway/issues/747#issuecomment-451805283
答案 0 :(得分:0)