【问题标题】:How to get reactive streams in Micronaut?如何在 Micronaut 中获取反应流?
【发布时间】:2021-02-23 15:34:22
【问题描述】:

在 Spring Boot 中,对于 Webflux 项目,我们通过在 HTTP 请求中发送标头 - “Accept: application/stream+json”来请求数据流。

如果我们发送“Accept: application/json”,我们会得到一个有效的 Json。

然而,在 Micronaut 中,如果我发送“Accept: application/stream+json”,则会引发错误。

{
    "message": "Specified Accept Types [application/x-json-stream] not supported. Supported types: [application/json]",
    "_links": {
        "self": {
            "href": "/carts/reactive",
            "templated": false
        }
    }
}

Micronaut 中的“Accept: application/stream+json”是什么意思?

【问题讨论】:

  • 接受相关请求的@Controller方法的签名是什么?
  • 它只是有一个@Get注解。消费者提到,没有产品。在 Spring Boot 中,我们可以使用“Accept”标头来控制流式传输。我们不能在 Micronaut 中做同样的事情吗?
  • @JeffScottBrown @Get("/cart/reactive") public Mono getCartReactively() { return cartClient.getCartReactively() .doOnNext(cart -> log.info("退回的购物车:" +购物车)); }
  • 您是否尝试使用“application/x-json-stream”作为 Accept 标头,我相信它与 Micronaut 中的等价物
  • @ManinderReddy 是的。这是我最初的想法。它没有用。我收到错误“不支持指定的接受类型 [application/x-json-stream]”

标签: micronaut reactor micronaut-client micronaut-rest


【解决方案1】:

Micronaut 中的“Accept: application/stream+json”是什么意思?

正如 cmets 中已经提到的,它是 application/x-json-stream。 (遗憾的是,对于流式 json 的内容类型,还没有一个既定标准,至少现在还没有。)

这里的问题是客户端如何控制响应类型——Json/stream。您正在使用produce = {MediaType.APPLICATION_JSON_STREAM,这意味着返回类型始终是流。在 Spring Boot 中,我们可以使用 Accept header 来控制我们想要的响应类型。我期待 Micronaut 也有同样的行为。

Micronaut 也可以做到这一点 - 您可以将多个值传递给 produces 参数,它会相应地返回流式或标准 JSON:

@Get(value = "/", produces = {MediaType.APPLICATION_JSON_STREAM, MediaType.APPLICATION_JSON})
public Flux<Foo> getFoos() {
    return Flux.range(1, 3).map(i -> new Foo("Number " + i));
}

@Value
class Foo {
    private String content;
}

然后我们可以使用application/x-json-stream 查询端点以检索 JSON 流:

 > curl localhost:8080 -H "Accept: application/x-json-stream"
{"content":"Number 1"}{"content":"Number 2"}{"content":"Number 3"}

...或纯 application/json 检索标准 JSON 数组:

 > curl localhost:8080 -H "Accept: application/json"
[{"content":"Number 1"},{"content":"Number 2"},{"content":"Number 3"}]

如果您想对每种类型的接受标头的行为进行更多自定义控制,那么您可以完全定义单独的控制器方法:

@Get(value = "/", produces = MediaType.APPLICATION_JSON_STREAM)
public Flux<Foo> getFoosStream() {
    return Flux.range(1, 3).map(i -> new Foo("Reactive " + i));
}

@Get(value = "/", produces = MediaType.APPLICATION_JSON)
public List<Foo> getFoosStandard() {
    return List.of(new Foo("Standard 1"), new Foo("Standard 2"), new Foo("Standard 3"));
}

...根据您发送的标头,将执行不同的方法(如上所述,您将能够使用标准 curl 命令看到差异。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多