WebFlux扩展未检索第二个请求

问题描述 投票:2回答:1

我正在尝试使用Spring的webflux创建一个http端点,以使用Github的api流github用户。我试图做描述的herehere,但是扩展似乎没有从github的api中获取结果的第二页。我究竟做错了什么?这是我当前拥有的代码:

@RestController
@RequestMapping("/user")
public class GithubUserController {

  private static final String GITHUB_API_URL = "https://api.github.com";

  private final WebClient client = WebClient.create(GITHUB_API_URL);

  @GetMapping(value = "/search/stream", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
  public Flux<GithubUser> search(
      @RequestParam String location,
      @RequestParam String language,
      @RequestParam String followers) {

    return fetchUsers(
            uriBuilder ->
                uriBuilder
                    .path("/search/users")
                    .queryParam(
                        "q",
                        String.format(
                            "location:%s+language:%s+followers:%s", location, language, followers))
                    .build())
        .expand(
            response -> {
              var links = response.headers().header("link");
              Pattern p = Pattern.compile("<(.*)>; rel=\"next\".*");
              for (String link : links) {
                Matcher m = p.matcher(link);
                if (m.matches()) {
                  return client.get().uri(m.group(1)).exchange();
                }
              }
              return Flux.empty();
            })
        .flatMap(response -> response.bodyToFlux(GithubUsersResponse.class))
        .flatMap(parsedResponse -> Flux.fromIterable(parsedResponse.getItems()))
        .log();
    }

  private Mono<ClientResponse> fetchUsers(Function<UriBuilder, URI> url) {
    return client.get().uri(url).exchange();
  }
}

我可以看到第二页的正则表达式起作用,因为如果我在if中添加打印,它会被打印,但是如果我在浏览器或邮递员上进行测试,则只会得到返回结果的第一页的结果通过github的api:

{"login":"chrisbanes","id":"227486"}
{"login":"keyboardsurfer","id":"336005"}
{"login":"lucasr","id":"730395"}
{"login":"hitherejoe","id":"3879281"}
{"login":"StylingAndroid","id":"933874"}
{"login":"rstoyanchev","id":"401908"}
{"login":"RichardWarburton","id":"328174"}
{"login":"slightfoot","id":"906564"}
{"login":"tomwhite","id":"85085"}
{"login":"jstrachan","id":"30140"}
{"login":"wakaleo","id":"55986"}
{"login":"cesarferreira","id":"277426"}
{"login":"kevalpatel2106","id":"20060162"}
{"login":"jodastephen","id":"213212"}
{"login":"caveofprogramming","id":"19751656"}
{"login":"AlmasB","id":"3594742"}
{"login":"scottyab","id":"404105"}
{"login":"makovkastar","id":"1076309"}
{"login":"salaboy","id":"271966"}
{"login":"blundell","id":"655860"}
{"login":"PierfrancescoSoffritti","id":"7457011"}
{"login":"0xddr","id":"4354177"}
{"login":"irsdl","id":"1798313"}
{"login":"andreban","id":"1733592"}
{"login":"TWiStErRob","id":"2906988"}
{"login":"geometer","id":"344328"}
{"login":"neomatrix369","id":"1570917"}
{"login":"nebraslabs","id":"32421477"}
{"login":"lucko","id":"8352868"}
{"login":"isabelcosta","id":"11148726"}
java spring-boot spring-webflux flux
1个回答
0
投票

Github API中的link标头提供了转义格式的URI。您传递给client.get().uri()的字符串应该不转义-因此它转义了转义的字符串,最后得到的URL不返回任何内容。

相反,您可能想使用类似以下内容的东西:

if (m.matches()) {
    return client.get().uri(URI.create(m.group(1))).exchange();
}

旁注-您的正则表达式也可能要考虑“下一个”链接之前的任意数量的字符,否则您将无法越过第二页,因此您可能希望在其前面加上.*

Pattern p = Pattern.compile(".*<(.*)>; rel=\"next\".*");

第二面说明-Github的API受速率限制(如果未经身份验证,则严重限制速率),因此您很可能会遇到这些速率限制。您可能希望以某种方式优雅地处理这种情况,但这是一个相当大的话题,超出了此问题的范围。

© www.soinside.com 2019 - 2024. All rights reserved.