Spring Cloud Gateway 过滤器获取 POST 请求体 (不使用 Lambda)
Spring Cloud Gateway 过滤器获取 POST 请求体 (不使用 Lambda)
在 Spring Cloud Gateway 过滤器中获取 POST 方法的请求体,可以通过继承 AbstractGatewayFilterFactory 类并重写 filter 方法来实现。以下是一个示例代码:
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
@Component
@Slf4j
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> {
public CustomGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
MediaType mediaType = request.getHeaders().getContentType();
if (request.getMethod() == HttpMethod.POST && mediaType != null
&& mediaType.isCompatibleWith(MediaType.APPLICATION_FORM_URLENCODED)) {
// 获取 POST 请求体
Mono<MultiValueMap<String, String>> formDataMono = request
.getBody()
.flatMap(body -> new ServerRequestWrapper(exchange,
HandlerStrategies.withDefaults().messageReaders())
.formData()
.defaultIfEmpty(MultiValueMap.empty()));
return formDataMono.flatMap(formData -> {
// 对请求体进行处理
// ...
// 重新设置请求体
BodyInserter<Mono<MultiValueMap<String, String>>, ReactiveHttpOutputMessage> bodyInserter =
BodyInserters.fromPublisher(formDataMono, new ParameterizedTypeReference<MultiValueMap<String, String>>() {});
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, exchange.getResponse().getHeaders());
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
ServerHttpRequest decorator = request.mutate()
.headers(httpHeaders -> httpHeaders.putAll(outputMessage.getHeaders()))
.body(outputMessage.getBody())
.build();
return chain.filter(exchange.mutate().request(decorator).build());
}));
});
}
return chain.filter(exchange);
};
}
public static class Config {
// 配置项
}
}
在这个示例中,我们首先通过 ServerHttpRequest 的 getBody 方法获取请求体,然后利用 ServerRequestWrapper 类封装 ServerHttpRequest,再利用 HandlerStrategies.withDefaults().messageReaders() 创建 ServerRequest 对象,最后通过 formData 方法获取 POST 请求的表单数据。
接下来,我们可以对请求体进行处理,并且重新设置请求体,然后将请求传递给下一个过滤器(或者服务)。
原文地址: https://www.cveoy.top/t/topic/Nof 著作权归作者所有。请勿转载和采集!