cURL 在访问 GitHub /search/users API 但使用 restTemplate.exchange returns 零用户时有效

cURL works while accessing GitHub /search/users API but using restTemplate.exchange returns zero users

我已经定义了一个 RestTemplate 支持的 HttpClient 来调用 Github API 来搜索用户

我的方法是这样的

public List<User> fetchPublicInformation(String firstName, String lastName, String location) {

    final HttpHeaders headers = new HttpHeaders();
    if (token != null && token.length() != 0) {
        headers.set("Authorization", "bearer " + token);
    }
    headers.set("'User-Agent'", "request");
    HttpEntity<String> entity = new HttpEntity<String>(headers);

    synchronized (this) {

        StringBuilder uri = new StringBuilder(GITHUB_SEARCH + "users?q=fullname:");
        if (!firstName.isEmpty()) {
            uri.append(firstName.trim().toLowerCase());
        } else {
            firstName = " ";
        }
        if (!lastName.isEmpty()) {
            uri.append(" " + lastName.trim().toLowerCase());
        } else {
            lastName = " ";
        }
        if (location != null && !location.isEmpty()) {
            uri.append("+location:" + location.trim().toLowerCase());
        }
        System.out.println(uri.toString());
        ResponseEntity<GitHubUsersResponse> response = null;
        response = template.exchange(uri.toString(), HttpMethod.GET, entity, GitHubUsersResponse.class);
        return response.getBody().getItems();
    }
}

此方法命中 URI

https://api.github.com/search/users?q=fullname:shiva tiwari+location:bangalore

和return []作为项目(响应正文的一部分)

而如果我将相同的 URI 与 cURL 一起使用,它会给我四个响应。

我找不到我的错。

在评论中与 OP 进行调查,我们发现他没有使用 java 的 url 和 curl,所以他得到了不同的结果。

他是运行这个命令:

$ curl https://api.github.com/search/users?q=fullname:shiva tiwari+location:bangalore
{
  "total_count": 1230,
  "incomplete_results": false,
  "items": [
    {
      "login": "Shiva108",
      "id": 13223532,
...

它产生的输出包含“items”数组中的几个对象,而使用 java 代码他得到一个空的“items”数组。

url中的space字' '很关键! shell 使用 space 分隔命令的参数,当它们在参数中时需要正确转义。

OP 与 curl 一起使用的 url 实际上只是 https://api.github.com/search/users?q=fullname:shiva,最后一部分被解释为 curl 的另一个参数(并且还产生了一个错误 curl: (3) URL using bad/illegal format or missing URL),而 java 使用完整的 url,包括姓氏和位置过滤器。

url 中的文字 space ' ' 也是非法字符,需要使用 +%20 进行编码(参见 Percent-encoding),实际上,如果我们使用引号 ' 来转义 shell 中的 space,我们会得到“400 Bad Request”:

$ curl -v 'https://api.github.com/search/users?q=fullname:shiva tiwari+location:bangalore'
...
< HTTP/1.0 400 Bad Request
...

但使用适当的 space 编码,我们得到与 java 相同的结果(空“items”数组):

$ curl 'https://api.github.com/search/users?q=fullname:shiva+tiwari+location:bangalore'
{
  "total_count": 0,
  "incomplete_results": false,
  "items": [

  ]
}
$

(我很确定 java 代码会自动处理 space 编码)