重复使用新参数的WebClient获取 [英] Repeat a WebClient get with new parameters

查看:197
本文介绍了重复使用新参数的WebClient获取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发Spring WebFlux应用程序,并且有一个Web适配器,可用来调用我使用的外部api方法. api之一使用带有rel ="next"的链接头进行分页.在下一个链接不存在之前,我需要调用此api,但是我不确定如何实现此目的.以下是我当前正在使用的基本通话:

I am developing a Spring WebFlux application and I have a web adapter that I use to call the external api methods that I use. One of the apis has a paginated result using a link header with a rel="next". I need to call this api until this next link does not exist but I am unsure how to achieve this. Below is the basic call that I am currently using:

public Flux<ItemDto> getAllItems(){
   return webClient.get() //The headers and base url for the api are defined in the constructor
        .uri("/api/items?limit=200") //limit is the number of items returned with 200 being the maximum
        .retrieve()
        .bodyToFlux(Map.class)
        .map(ItemConverter::mapValueToItemDto);//This is just a conversion method that handles mapping
}

我需要的是能够重复此调用,但添加基于带有下一个" rel值的链接头的一部分的请求参数.

What I am needing is to be able to repeat this call but add a request param that is based on part of the link header with the "next" rel value.

我已经看到使用扩展或重复的提法,但是我不确定如何精确地使用它们.我知道使用交换是抓取clientResponse所必需的,这样我就可以获取标头.

I've seen mention of using expand or repeat but I am not sure how exactly to use them. I know using exchange is necessary to grab the clientResponse so I can get the headers.

这个问题可能有点含糊,因此如有需要,我可以提供任何澄清.

This question is probably decently vague so I can provide any clarification if needed.

谢谢!

更新

我一直在尝试各种事情,并且发现了几乎可以奏效的东西.

I've been attempting various things and found something that almost works.

public Flux<ItemDto> getAllItems(){
   return recursiveMethod("")//Start with the first page basically
      .flatMap(clientResponse ->
           clientResponse.bodyToFlux(Map.class)
                .map(ItemConverter::mapValueToItemDto));
}

private Flux<ClientResponse> recursiveMethod(String after){
   return webClient.get()
            .uri("/api/items?limit=3" + after) //The test list I am using is only 9 items so I'm using 3 for good results
            .exchange()
            .expand(clientResponse -> {
                List<String> links = clientResponse.headers().asHttpHeaders().getValuesAsList("LINK");
                if(links.stream().anyMatch(link->link.contains("rel=\"next\""))){
                    for (String link : links){
                        if (link.contains("rel=\"next\"")){
                            return recursiveMethod("&" + link.substring(link.indexOf("after="), link.indexOf("&"))); 
                            //The header link has limit and after switched, that's why this looks a little odd
                        }
                    }
                }
                return Flux.empty();
            });
}

唯一的问题是它最终会重复最后一个页面",例如:项目1,项目2,项目3,项目4,项目5,项目6,项目7,项目8,项目9,项目7.项目8,项目9. 不知道这是由于我设置的递归还是由于Flux引起的,还是因为我可能滥用了expand方法.

The only issue is that it ends up repeating the last "page", eg: Item 1, Item 2, Item 3, Item 4, Item 5, Item 6, Item 7, Item 8, Item 9, Item 7, Item 8, Item 9. Not sure whether this is due to the recursion I've set up or because of Flux or because I am possibly misusing the expand method.

推荐答案

经过大量的试验和错误并找到了针对特定部分的解决方案之后,我找到了适合我的解决方案.

After lots of trial and error and finding solutions to specific parts of this, I found the solution that worked for me.

public Flux<ItemDto> getAllItems() {
    webClient.get()
            .uri("/api/items?limit=1")//Used one to test
            .exchange()
            .expand(clientResponse -> {
                List<String> links = clientResponse.headers().asHttpHeaders().getValuesAsList("LINK");
                if(links.stream().anyMatch(link->link.contains("rel=\"next\""))){
                    for (String link : links){
                        if (link.contains("rel=\"next\"")){
                            return webClient.get()
                                    .uri("/api/items?limit=1&" + link.substring(link.indexOf("after="), link.indexOf("&")))
                                    .exchange();
                        }
                    }
                }
                return Flux.empty();
            })
            .flatMap(clientResponse ->
                    clientResponse.bodyToFlux(Map.class)
                            .map(ItemConverter::mapValueToItemDto));
}

无需任何递归.使用expand更合适.现在,实际上可以将其中的一部分(参见下文)分解为自己的方法,但是由于只有几行,我选择不这样做.

No need for any recursion. Just more appropriately using expand. Now, part of this (see below) can actually be broken off into its own method, but since it's only a few lines I opted not to do this.

webClient.get()
   .uri("/api/items?limit=1" + after)//This after bit would be like what was passed as an argument before
   .exchange();

这篇关于重复使用新参数的WebClient获取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆