我想在带有 Kotlin 的 Spring WebFlux 上的 REST API 中集中记录请求和响应。到目前为止,我已经尝试过这种方法
@Bean
fun apiRouter() = router {
(accept(MediaType.APPLICATION_JSON) and "/api").nest {
"/user".nest {
GET("/", userHandler::listUsers)
POST("/{userId}", userHandler::updateUser)
}
}
}.filter { request, next ->
logger.info { "Processing request $request with body ${request.bodyToMono<String>()}" }
next.handle(request).doOnSuccess { logger.info { "Handling with response $it" } }
}
这里请求方法和路径日志成功,但正文是 Mono
,那么我应该如何记录呢?是否应该反过来,我必须订阅请求正文 Mono
并将其记录在回调中?另一个问题是 ServerResponse
这里的接口无法访问响应体。我怎么能在这里得到它?
我尝试过的另一种方法是使用 WebFilter
@Bean
fun loggingFilter(): WebFilter =
WebFilter { exchange, chain ->
val request = exchange.request
logger.info { "Processing request method=${request.method} path=${request.path.pathWithinApplication()} params=[${request.queryParams}] body=[${request.body}]" }
val result = chain.filter(exchange)
logger.info { "Handling with response ${exchange.response}" }
return@WebFilter result
}
同样的问题:请求正文是 Flux
并且没有响应正文。
有没有办法访问来自某些过滤器的日志记录的完整请求和响应?我不明白什么?
原文由 Koguro 发布,翻译遵循 CC BY-SA 4.0 许可协议
这或多或少类似于 Spring MVC 中的情况。
在 Spring MVC 中,您可以使用
AbstractRequestLoggingFilter
过滤器和ContentCachingRequestWrapper
和/或ContentCachingResponseWrapper
。这里有许多权衡:ContentCaching*Wrapper
中不存在类,但您可以创建类似的类。但请记住这里的其他要点:DataBuffer
实例,它们是(大致)内存高效字节数组。这些属于缓冲池,并被回收用于其他交换。如果这些没有正确保留/释放,则会创建内存泄漏(并且缓冲数据以供以后使用肯定适合这种情况)您的问题的其他答案:
WebFilter
可能是最好的方法flatMap
上请求和缓冲数据在doOn
运营商