Spring Webflux WebClient嵌套get

qoefvg9y  于 2023-05-21  发布在  Spring
关注(0)|答案(1)|浏览(179)

我正在努力实现我的WebClient,我称之为“同步操作”
我需要做一个嵌套调用,因为我必须获取项目IDs的列表,然后通过ID单独调用每个项目,以将完整的对象放入我的DB中。
我目前的工作解决方案似乎不干净,因为我有时会得到“操作超时”,我需要得到一个通知时,所有的项目被提取/更新
当前解决方案

this.webClient.get()
    .uri(locationURI)
    .accept(MediaType.APPLICATION_JSON)
    .exchangeToMono(clientResponse -> clientResponse.bodyToMono(LocationNevarisDto.class))
    .subscribe(locationDto -> {

        List<ProjectInfosNevarisDto> projectInfos = new ArrayList<>(locationDto.getProjektInfos());

        for (ProjectInfosNevarisDto projectInfosNevarisDto:projectInfos) {

            this.webClient.get()
                .uri(projectURI + projectInfosNevarisDto.getId())
                .accept(MediaType.APPLICATION_JSON)
                .exchangeToMono(clientResponse -> clientResponse.bodyToMono(ProjectNevarisDto.class))
                .subscribe(projectNevaris -> {

                    if("AF".equals(projectNevaris.getStatus())) {
                        projectService.saveNevarisProject(projectNevaris);
                    }
                });
    }
});

LocationNevarisDto包含一个项目列表,还有IDs。我使用这个列表并将其放入foreach中,然后调用getevery项目及其完整属性以保存到DB中。
更新日期:

@Data
public class LocationNevarisDto {

    private String id;
    private String bezeichnung;
    private DatenbankInfo datenbankInfo;

    @Data
    public static class DatenbankInfo {
        private String server;
        private String datenbank;
        private String benutzername;
    }

    private List<ProjectInfosNevarisDto> projektInfos;
}
cxfofazt

cxfofazt1#

您希望使用流处理,以便代码更干净。

public Mono<Void> doIt() {
    return this.webClient.get()
        .uri(locationURI)
        .accept(MediaType.APPLICATION_JSON)
        .exchangeToMono(clientResponse -> clientResponse.bodyToMono(LocationNevarisDto.class))
        .flatMapIterable(LocationNevarisDto::projektInfos)
        .flatMap( this::saveProjectInfo).last();
  }

  private Mono<Void> saveProjectInfo(ProjectInfosNevarisDto dto) {
    return this.webClient.get()
        .uri(projectURI + dto.id())
        .accept(MediaType.APPLICATION_JSON)
        .exchangeToMono(clientResponse -> clientResponse.bodyToMono(ProjectNevarisDto.class))
        .filter( (projectNevaris) -> Objects.equals("AF", projectNevaris.status()))
        .flatMap( projectService::saveNevarisProject);
  }

像这样的东西应该可以。使用mapfilter和专门的方法将单声道转换为通量,您可以进行很好的流处理。需要记住的一件事是,你的整个链和返回类型也需要是响应式的,否则在调用saveNevarisProject时,你可能需要在Mono.just中添加一些额外的 Package 。
我还冒昧地使用了record类来代替classes和lombok @Data注解。然而,事情的要点应该是清楚的。

相关问题