Spring Webflux обеспечивает потоковую поддержку конечной точки контроллера из коробки, если вы запрашиваете конечную точку, возвращающую Flux<Foo>
с Accept: application/stream+json
или Accept: text/event-stream
.
Теперь я хотел бы представить другое представление Foo
OtherFoo
, который должен быть возвращен из нашей /foos
конечной точки через Accept: application/prs.other-foo-stream+json
(например).
Теперь я попытался протестировать всю установку, используя следующий код
data class Foo(
val id: UUID = UUID.randomUUID()
)
@RestController
@RequestMapping("/test")
class TestController(
webClientBuilder: WebClient.Builder
) {
private val client = webClientBuilder
.baseUrl("http://localhost:8080/test")
.build()
private fun data() = Flux.range(0, 3)
.map { Foo() }
.delayElements(Duration.ofSeconds(1))
@GetMapping
fun findAll() = data()
@GetMapping(produces = ["application/x.foo+json"])
fun findAllAsFoo() = data()
@GetMapping(produces = ["application/x.foo-stream+json"])
fun findAllAsFooSse(): Flux<ServerSentEvent<Foo>> = data()
.map {
ServerSentEvent.builder<Foo>()
.data(it)
.build()
}
@PostMapping
fun test(@RequestParam accept: String) = client
.get()
.accept(MediaType.parseMediaType(accept))
.retrieve()
.bodyToFlux<Foo>()
}
Отображения запроса выглядят нормально, и если вы запрашиваете пользовательскую конечную точку GET напрямую, ответ возвращается через SSE
➜ http --stream :8080/test "Accept: application/x.foo-stream+json"
HTTP/1.1 200 OK
Content-Type: text/event-stream;charset=UTF-8
transfer-encoding: chunked
data:{"id":"54d6570d-9ee4-4792-adce-1be035f20bc3"}
data:{"id":"87f50fbc-2780-4730-a11c-2165e975614b"}
data:{"id":"557cacca-9e3d-4322-b7ef-b2201301a636"}
Если я запрашиваю конечную точку с помощью "WebClient
redirect" через
➜ http -v --stream POST :8080/test accept=="application/x.foo-sse+json" "Accept: application/stream+json"
POST /test?accept=application%2Fx.foo-sse%2Bjson HTTP/1.1
Accept: application/stream+json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: localhost:8080
User-Agent: HTTPie/2.1.0
HTTP/1.1 200 OK
Content-Type: application/stream+json
transfer-encoding: chunked
{
"id": "d1bc7075-eef7-460a-ad72-1440a432fcb5"
}
{
"id": "6e1a4384-cb5b-445d-9fd9-d05f53fda5f8"
}
{
"id": "b7c31c5f-1344-4afc-a4b1-5688fa5fc1c3"
}
ответ также передается в потоковом режиме, но я получаю все сообщения одновременно (обратите внимание на 1-секундную задержку в data()
), что говорит о том, что WebClient
на самом деле не передает поток, если он не запрашивает сам поток, используя .accept()
.
Настраиваемая конечная точка отвечает Content-Type: text/event-stream;charset=UTF-8
, хотя WebClient
должно быть хорошо, принимая ответ в виде потока.
Есть ли способ обслуживания (I thi Эта часть решена путем возврата Flux<ServerSentEvent<*>>
) и извлечения потоков с пользовательскими типами мультимедиа с помощью Webflux / WebClient
?