REST-下载用户列表

时间:2018-10-05 07:28:37

标签: java spring rest spring-boot

上下文:

我想编写一个端点,该端点将根据用户名返回Collection个用户。那些用户名应如何传递到REST端点-请注意,我可以(可能)拥有很多用户名(例如> 5000)

解决方案1:

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

@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端点并将用户名列表作为请求正文传递。尽管从编码的角度来看,这种方法更为简洁,但最终还是使用POST来获取数据。

@RestController
public class UserController { 

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

}

问题:

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

编辑:

  • 我已经根据答案的建议更新了第一个解决方案的签名。 Spring可以反序列化filename1,filename2@RequestParam的列表中。

4 个答案:

答案 0 :(得分:1)

POST在这种情况下看起来更干净,因为-

  1. 在URL中发送一个巨大的字符串不是一个好主意,并且有可能出现错误
  2. 您需要编写其他代码(逻辑)以在前端创建字符串并将其在后端拆分。
  3. 在URL中发送巨大的字符串是不可扩展的,因为URL的长度受到限制。

答案 1 :(得分:0)

由于URL长度受到限制,因此获取方法可能会导致问题,然后必须限制查询参数。

尽管这不是发帖请求,但就您而言,我认为发帖是唯一的出路。

答案 2 :(得分:0)

GET不受限制,但浏览器受限制。您的服务器客户端似乎不是浏览器,所以我想说GET是必经之路。

PS GET可以接收到一个正文(不是很好,但是POST也不是最佳匹配)。

您不需要连接字符串并在服务器服务器上添加额外的计算,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标头属性

server.max-http-header-size=30000 

答案 3 :(得分:0)

我同意上面给出的所有答案。我想再指出一点,如果您要进行发布请求,则可能必须增加服务器可以接收的有效负载容量,春季启动的默认发布容量(最大大小(以字节为单位))为2mb(基于服务器) )。在测试代​​码时,使用1000-2000个用户名可能会很好,但是请确保更改属性以在请求中接受更多字节。