我正在开发一个 Spring Cloud Gateway 项目,我需要使用 GlobalFilter 记录传入请求 URI、正文和关联路由。有推荐的方法来实现这一目标吗?
我探索了各种选项,包括实现自定义 GlobalFilter,但在记录路由以及请求 URI 和正文时遇到困难。这是我当前的实现:
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.logging.Logger;
@Component
public class LoggingFilter extends AbstractGatewayFilterFactory<Object> {
private static final Logger logger = Logger.getLogger(LoggingFilter.class.getName());
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// Logging request URI
logger.info("Incoming request URI: " + request.getURI());
// Logging request body for POST and PUT requests
if (request.getMethodValue().equalsIgnoreCase("POST") || request.getMethodValue().equalsIgnoreCase("PUT")) {
return exchange.getRequest().getBody()
.flatMap(body -> {
String requestBody = bufferToString(body);
logger.info("Request body: " + requestBody);
return chain.filter(exchange);
});
}
return chain.filter(exchange);
};
}
private String bufferToString(DataBuffer dataBuffer) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
return new String(bytes);
}
}
@Slf4j
public class GatewayRequestLoggingFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// Log request body for POST and PUT requests
if (exchange.getRequest().getMethodValue().equalsIgnoreCase(HttpMethod.POST) ||
exchange.getRequest().getMethodValue().equalsIgnoreCase(HttpMethod.PUT)) {
return exchange.getRequest().getBody()
.map(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String requestBody = new String(bytes);
log.info("Incoming request URI: {} with body: {}", exchange.getRequest().getURI(), requestBody);
return exchange;
}).then(chain.filter(exchange));// Return Mono<Void>
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 1;
}
}