CoroutineWebFilter.kt:
package com.example.webflux.filter
import kotlinx.coroutines.reactive.awaitSingleOrNull
import kotlinx.coroutines.reactor.mono
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono
abstract class CoroutineWebFilter(
/**
* true - only execute once during one request; false - execute every time even if the request was forwarded by handler A to handler B
*/
private val once: Boolean = false
) : WebFilter {
private val processFlag = "__FILTER_PROCESSED_" + javaClass.name
final override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
val flag = if (once) exchange.getAttribute<Any>(processFlag) else null
return if (flag == null) mono {
if (beforeChain(exchange)) {
chain.filter(exchange).awaitSingleOrNull()
afterChain(exchange)
}
null
} else Mono.empty()
}
/**
* @return true - continue to next step; false - skip all remain steps and return to client
*/
abstract suspend fun beforeChain(exchange: ServerWebExchange): Boolean
abstract suspend fun afterChain(exchange: ServerWebExchange)
}
网友评论