SpringCloud入门(十二):网关Gateway 获取Post请求体(Greenwich.SR2)
前言在学习gateway的时候,使用全局过滤器GlobalFilter,来拦截请求的时候,网上的例子基本都是使用Get来完成的,很少使用Post来测试,导致在使用Post的时候,获取不到Body的内容。实现方式/*** 全局过滤器* 可拦截get、post等请求做逻辑处理* @author hero良* @className RequestGlobalFilter* @d...
·
前言
在学习gateway的时候,使用全局过滤器GlobalFilter,来拦截请求的时候,网上的例子基本都是使用Get来完成的,很少使用Post来测试,导致在使用Post的时候,获取不到Body的内容。
实现方式
/**
* 全局过滤器
* 可拦截get、post等请求做逻辑处理
* @author hero良
* @className RequestGlobalFilter
* @description
*/
@Slf4j
@Component
public class RequestGlobalFilter implements GlobalFilter, Ordered {
/**
*
* @param exchange
* @param chain
* @return
*/
@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);
//TODO 得到Post请求的请求参数后,做你想做的事
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);
});
//下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
//封装request,传给下一级
return chain.filter(exchange.mutate().request(mutatedRequest).build());
});
} else if ("GET".equals(method)) {
Map requestQueryParams = request.getQueryParams();
//TODO 得到Get请求的请求参数后,做你想做的事
return chain.filter(exchange);
}
return chain.filter(exchange);
}
/**
* 执行顺序
* @return
*/
@Override
public int getOrder() {
return 1;
}
}
用缓存的方式来获取
/**
* @author hero良
* @className CacheBodyGatewayFilter
* @description
* @date 2019/12/12 16:35
*/
@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;
}
}
/**
* @author hero良
* @className VerifyGatewayFilter
* @description
* @date 2019/12/12 16:36
*/
@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
更多推荐
已为社区贡献4条内容
所有评论(0)