代码之家  ›  专栏  ›  技术社区  ›  user10367961

REST-下载用户列表

  •  2
  • user10367961  · 技术社区  · 8 年前

    上下文:

    我想写一个端点,它将返回 Collection 基于用户名的用户。如何将这些用户名传递给REST端点- 请注意,我可以(潜在地)拥有许多用户名(例如>5000) ?

    解决方案1:

    使用 GET 端点,连接客户端的用户名并将其作为单个请求参数传递。在服务器端拆分请求参数以获取用户名列表。

    @RestController
    public class UserController { 
    
        @GetMapping
        // able to deserialize `filename1,filename2` to List out of the box
        public Collection<User> getUser(@RequestParam List<String> usernames) {
            return userService.getUsersByUsername(usernames);
        }
    
    }
    

    解决方案2:

    使用 POST 结束并将用户名列表作为请求正文传递。虽然cleaner形成了一个编码透视图,但我最终使用 岗位 获取数据。

    @RestController
    public class UserController { 
    
        @PostMapping
        public Collection<User> getUser(@RequestBody List<String> usernames) {
            return userService.getUsersByUsername(usernames);
        }
    
    }
    

    问题:

    1. 两种解决方案中哪一种比较好?
    2. 是否有更好的方法将用户名列表传递到端点?

    编辑:

    • 我已经根据答案中的建议更新了第一个解决方案的签名。Spring能够反序列化 filename1,filename2 开箱即用 @RequestParam .
    4 回复  |  直到 7 年前
        1
  •  1
  •   Rishikesh Dhokare    8 年前

    POST 在这种情况下看起来是一种更干净的方法,因为-

    1. 在URL中发送一个巨大的字符串不是一个好主意,而且有可能出错
    2. 您需要编写额外的代码(逻辑)来在前端创建字符串并在后端拆分它。
    3. 在URL中发送一个巨大的字符串是不可伸缩的,因为URL的长度有限制。
        2
  •  0
  •   saurav    8 年前

    Get方法可能会导致一个问题,因为URL长度是有限的,然后必须限制查询参数。

    虽然这不是一个邮政要求,但在你的情况下,我认为邮政是唯一的出路。

        3
  •  0
  •   kashish verma    8 年前

    我同意上面给出的所有答案。我想指定另外一点,如果你要用POST请求,你可能不得不增加服务器可以接收的有效负载容量,Spring Bug的默认后容量(最大字节大小)是2MB(基于服务器)。在测试代码时,可以使用1000-2000个用户名,但请确保更改属性以接受请求中的更多字节。

        4
  •  0
  •   Adina Rolea    8 年前

    GET不受限制,但浏览器是。您的服务器客户端似乎不是浏览器,所以我认为GET是一种方法。

    附笔 得到可以得到一个身体(不是很好,但邮政也不是最好的匹配)。

    您不需要连接字符串并在服务器服务器上添加额外的计算,GET可以接收单独字符串的列表。

    更新示例:

    @RestController
    public class MyController {
    
        @GetMapping(value = "/test")
        public List<String> getTestParams(@RequestParam List<String> params) {
            return params;
        }
    }    
    

    3000个参数的测试

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class TestMyController {
    
        @Autowired
        private TestRestTemplate restTemplate;
    
        @Test
        public void testRequestWithParamsList() {    
            List<String> params = new ArrayList<>();
            for (int i = 0; i < 3000; i++) {
                params.add(String.valueOf(i));
            }
    
            List<String> result = restTemplate.getForObject(buildUrl(params),
                    List.class);
    
            assertEquals(params, result);
        }
    
        private String buildUrl(List<?> params) {
            return "/test?params=" + getUrlParameter(params);
    
        }
    
        private String getUrlParameter(List<?> params) {
            return params.stream()
                    .map(Object::toString)
                    .collect(Collectors.joining(","));
        }
    }    
    

    如果您使用的是tomcat,那么还必须在application.properties中指定max http header属性

    server.max-http-header-size=30000