【问题标题】:Passing List of Integers to GET REST API将整数列表传递给 GET REST API
【发布时间】:2015-03-13 12:18:31
【问题描述】:

我想从前端的数据库中获取实体列表。 所以我在 Spring MVC 中编写了 POST REST HTTP 调用。

但我阅读了 HTTP 文档,该文档说,每当您必须从数据库中检索数据时,首选 GET 调用。 那么,是否有任何我可以将 POST 调用替换为 Angular JS 中的 GET 调用并传递整数列表。 但是,GET HTTP 有很多缺点,比如:URL 的长度是有限的。考虑到我们必须从数据库中获取 1000 个实体的情况。

请建议我获取实体的可能方法或在 Spring MVC 中为整数列表编写 GET REST API(指实体 ID)。

例如:假设书台上有 100 本书,但我只想要几本书,比如 id : 5,65,42,10,53,87,34,23。 这就是为什么我在 POST 调用中将这个 ID 列表传递到整数列表中的原因。

目前卡住了如何将其转换为 GET 调用。简而言之,如何通过 GET REST 调用传递整数列表。

【问题讨论】:

    标签: web-services rest spring-mvc http-headers


    【解决方案1】:

    对于您的问题,我更喜欢通过 HTTP 路径变量的变体,因为在 REST 意识形态中,资源 ID 在资源名称“http://../resource/id”之后传递,并且 HTTP 参数用于过滤。

    通过 HTTP 参数

    如果您需要通过 HTTP 参数传递您的 id,请参见下面的示例:

    这是你的 Spring MVC 控制器方法:

    @RequestMapping(value = "/books", params = "ids", method = RequestMethod.GET)
    @ResponseBody
    Object getBooksById_params(@RequestParam List<Integer> ids) {
        return "ids=" + ids.toString();
    }
    

    您可以使用下一个变体拨打电话:

    1. http://server:port/ctx/books?ids=5,65,42
    2. http://server:port/ctx/books?ids=5&ids=65&ids=42

    也看看这个讨论:https://stackoverflow.com/a/9547490/1881761


    通过 HTTP 路径变量

    您也可以通过路径变量传递您的 id,请参见下面的示例:

    @RequestMapping(value = "/books/{ids}", method = RequestMethod.GET)
    @ResponseBody
    Object getBooksById_pathVariable(@PathVariable List<Integer> ids) {
        return "ids=" + ids.toString();
    }
    

    您的电话将如下所示:http://server:port/ctx/books/5,65,42


    【讨论】:

    • 这是国际海事组织的正确答案。 stackoverflow.com/questions/4541338/… 引用您必须自己进行标记化并接受为 String 但 Spring 为您处理自然 List 案例。有些人决定使用“POST”并传入列表,但这不是真正的宁静方法 IMO。它必须是 GET。
    • 关于路径变量场景,Jersey是否支持这种模式?
    【解决方案2】:

    GET HTTP 调用的优点:它总是用于检索数据。(从这个角度来看:我们应该为每个和检索实现)

    通过 HTTP 参数

    如果您需要通过 HTTP 参数传递您的 id,请参见下面的示例:

    这是你的 Spring MVC 控制器方法:

    @RequestMapping(value = "/book", params = "ids", method = RequestMethod.GET)
    @ResponseBody
    Object getBooksById_params(@RequestParam List<Integer> ids) {
    return "ids=" + ids.toString();
    }    
    

    它工作正常,但在特殊情况下:比如 URI 超过 2048 个字符。这意味着列表中有很多Id(例如:1000)

    然后它抛出一个异常: 返回 414(请求 URI 太长)

    这是http://www.checkupdown.com/status/E414.html

    经过一番研究,我的理解是:HTTP 协议对 URI 的长度没有任何先验限制。服务器必须能够处理它们所服务的任何资源的 URI,并且如果它们提供可以生成此类 URI 的基于 GET 的表单,则应该能够处理无限长度的 URI。如果 URI 比服务器可以处理的长,服务器应该返回 414(Request_URI Too Long) 状态。

    我也浏览过类似获取 GET URI 长度的网站:

    所以结论是,当在运行时可能存在可变 URI 长度以防止出现此类异常时,坚持 POST 调用[return 414 (Request-URI Too Long)]

    【讨论】:

    • 最好的办法是避免这种情况,并在后端处理这种情况,例如:发送情况的上下文:资源类别等
    • 是的,我们可以避免这种情况。因此,我在后端处理了这个。例如:booksCategories
    【解决方案3】:

    或者,为了允许复杂的查询,您需要为查询提供自己的 rest 语言。因此,要创建一个 POST 到 /library/query 的查询,然后使用带有数据 {id:34} 的 POST /library/query/12345 之类的内容对其进行编辑,然后使用 GET /library/books?query=12345

    【讨论】:

      【解决方案4】:

      你可以像这样调用列表:

      ***/users?id=1&id=2
      

      【讨论】:

        【解决方案5】:

        如果您想从 API 中读取实体,您必须使用 GET 调用。

        获取它们的更好方法是使用查询参数作为过滤器。

        REST DESIGN 每次都不能通过 id 检索多个实体。

        一个例子:

        GET /library/books/58731 -> 只返回一本由 58731 标识的书

        GET /library/books?numPages&gt;70返回所有超过70页的书

        我认为,如果您需要检索大量书籍,因为它们具有一些所有匹配的逻辑,请尝试将其作为 queryString。

        另一个例子:

        GET /library/books?stored&gt;20150101 返回 2015 年添加到图书馆的所有书籍

        如果您向我们提供有关收藏和要求的更多信息,我们将更直接地回答。

        【讨论】:

        • 谢谢,我明白了。但我被卡住了如何通过选定的 id's 。例如:考虑书表中有100本书,但我只想要几本书,比如id:5,65,42,10,53,87,34,23。这就是为什么我在 POST 调用的整数列表中传递这个 ID 列表。目前卡住了如何将其转换为 GET 调用。简而言之,如何通过 GET 调用传递整数列表。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 2017-02-06
        相关资源
        最近更新 更多