前言
在学习gateway的时候,使用全局过滤器GlobalFilter,来拦截请求的时候,网上的例子基本都是使用Get来完成的,很少使用Post来测试,导致在使用Post的时候,获取不到Body的内容。
实现方式
@Slf4j
@Component
public class RequestGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request= exchange.getRequest();
String method = request.getMethodValue();
if ("POST".equals(method)) {
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String bodyString = new String(bytes, StandardCharsets.UTF_8);
log.info("bodyString====={}",bodyString);
exchange.getAttributes().put("POST_BODY",bodyString);
DataBufferUtils.release(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
DataBuffer buffer = exchange.getResponse().bufferFactory()
.wrap(bytes);
return Mono.just(buffer);
});
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
return chain.filter(exchange.mutate().request(mutatedRequest).build());
});
} else if ("GET".equals(method)) {
Map requestQueryParams = request.getQueryParams();
return chain.filter(exchange);
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 1;
}
}
用缓存的方式来获取
@Component
public class CacheBodyGatewayFilter implements Ordered, GlobalFilter {
public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (exchange.getRequest().getHeaders().getContentType() == null) {
return chain.filter(exchange);
} else {
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
DataBufferUtils.retain(dataBuffer);
Flux<DataBuffer> cachedFlux = Flux
.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);
return chain.filter(exchange.mutate().request(mutatedRequest).build());
});
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
@Slf4j
@Component
public class VerifyGatewayFilter implements GlobalFilter, Ordered {
public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Object cacheBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);
if(cacheBody == null){
return chain.filter(exchange);
}
String raw = toRaw((Flux<DataBuffer>)cacheBody);
log.info(raw);
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 100;
}
private static String toRaw(Flux<DataBuffer> body) {
AtomicReference<String> rawRef = new AtomicReference<>();
body.subscribe(buffer -> {
byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes);
DataBufferUtils.release(buffer);
rawRef.set(Strings.fromUTF8ByteArray(bytes));
});
return rawRef.get();
}
}
两种方式都可以成功获取到请求体
SpringBoot版本为 2.1.7.RELEASE>
SpringCloud版本为 Greenwich.SR2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)