【问题标题】:Content Negotiation: Route according to Accept header in Micronaut内容协商:根据 Micronaut 中的 Accept 标头进行路由
【发布时间】:2020-03-06 02:08:33
【问题描述】:

在 HTTP 中,您可以定义一个 Acceptheader 来指定要检索的内容:

curl --header "Accept: text/plain" localhost:8080/greetings/
curl --header "Accept: application/xml" localhost:8080/greetings/

我想知道,Micronaut 是否有内置解决方案来处理这个问题。

有一篇博文 (https://mrhaki.blogspot.com/2018/08/micronaut-mastery-return-response-based.html) 描述了如何根据 Accept 标头产生不同的输出。但这对我来说感觉不对,因为 Micronaut 中的大多数事情都是由注释处理的。

我尝试使用@Consumes(MediaType.TEXT_PLAIN),但这仅适用于 POST 请求(这很明显,因为 Micronaut 不会使用 GET 请求中的数据)。 @Produces(MediaType.TEXT_PLAIN) 注解似乎设置了content type 标头并配置输出编码,但似乎与路由没有交互。

    @Produces(MediaType.APPLICATION_XML)
    @Get("/")
    String getXml() {
        return "<greeting>Hello World</greeting>";
    }

    @Produces(MediaType.TEXT_PLAIN)
    @Get("/")
    String getPlaintext() {
        return "Hello World";
    }

虽然我希望这会将带有 Accept: text/plain 的 HTTP 请求路由到 getPlaintext() 并将 Accept: application/xml 路由到 getXml(),但它会导致传入请求的 2 个匹配项:

DEBUG i.m.h.s.netty.RoutingInBoundHandler - Encoding emitted response object [More than 1 route matched the incoming request. The following routes matched /greetings/: GET - /greetings, GET - /greetings] using codec: io.micronaut.jackson.codec.JsonMediaTypeCodec@41ffaeb8

那么,是否有任何内置解决方案可以根据 Accept 标头路由 HTTP 请求?

【问题讨论】:

  • 我认为这不可能。 Micronaut 路线仅通过 uri 匹配选择。有一些关于using Accept header in API versions 的讨论。但是,UriRouteMatch 仍然没有考虑到MediaType
  • "Micronaut 路线仅通过 uri 匹配选择。" - 这是不正确的。 uri 是其中的一部分,但请求动词也是。
  • 也就是说……您可以将@Get("/someuri")@Post("/someuri") 附加到不同的方法,Micronaut 知道如何处理它。这无助于上述问题的真正含义,但它确实解决了“仅通过 uri 匹配选择 Micronaut 路线”的说法。我希望这是有道理的。

标签: micronaut


【解决方案1】:

路由目前不考虑接受标头,但是路由确实考虑了@ConsumesContent-Type 标头。您可以拥有具有相同 URL 并接受不同数据类型的路由,并且将选择与内容类型匹配的路由。

您可以在 Github 上创建一个问题以供讨论。它可能已经在那里,所以一定要先搜索

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 2010-12-31
    • 2015-04-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    相关资源
    最近更新 更多