在响应中,当将通量作为 ResponseEntity 返回时,我得到 scanAvailable=true

Rob*_*ena 7 java webclient reactive-programming spring-boot spring-webflux

当用户尝试将两个休息端点与 WebClient 一起使用时,我对获得正确的响应感到有点困惑。我想在代码中将其用作异步和非阻塞。

我正在从控制器返回通量。代码详情如下:

控制器类方法如下所示:

@RequestMapping(method = RequestMethod.GET, path = "/v1/repos/{userName}", produces = "application/json")
    public ResponseEntity<Flux<GithubRepo>> getUserReposDetails(
            @PathVariable(name="userName",required = true) String userName) throws Exception{
        return new ResponseEntity<>(this.getGitRepos(userName), HttpStatus.OK);
    }
Run Code Online (Sandbox Code Playgroud)

它正在调用getGitRepos方法。方法详情如下:

private Flux<GithubRepo> getGitRepos(String userName) {
        return webClient.get().uri("/users/{userName}/repos",userName).
                exchangeToFlux(clientResponse -> clientResponse.bodyToFlux(GithubRepo.class)).map(github->{
 github.setBranch(webClient.get()
.uri("/repos/{userName}/{branchName}/branches",userName,github.getBranch())
.retrieve().bodyToFlux(Branch.class).collectList());
                    return github;
                });
    }
Run Code Online (Sandbox Code Playgroud)

WebClient 是:

WebClient webClient =  WebClient.builder().baseUrl("https://api.github.com").
            defaultHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.github.v3+json").build();
Run Code Online (Sandbox Code Playgroud)

GitHub 和 Branch 类如下:

@Data
public class GithubRepo {
    private String name;
    private String ownerLogin;
    private Mono<List<Branch>> branch;
    
    @JsonProperty("owner")
    private void unpackNested(Map<String,String> commit) {
        this.ownerLogin = commit.get("login");
    }
}
Run Code Online (Sandbox Code Playgroud)
@Data
public class Branch {
    
    private String name;
    private Boolean protected;
}
Run Code Online (Sandbox Code Playgroud)

我收到的 JSON 响应为:

[
  {
    "name": "HelloWorld",
    "ownerLogin": "test",
    "branch": {
      "scanAvailable": true
    }
  },
  {
    "name": "rokehan",
    "ownerLogin": "test",
    "branch": {
      "scanAvailable": true
    }
  },
  {
    "name": "sNews",
    "ownerLogin": "test",
    "branch": {
      "scanAvailable": true
    }
  },
  {
    "name": "Test--01",
    "ownerLogin": "test",
    "branch": {
      "scanAvailable": true
    }
  }
]
Run Code Online (Sandbox Code Playgroud)

我想得到的响应是:

[
  {
    "name": "HelloWorld",
    "ownerLogin": "test",
    "branch": [
      {
        "name": "asd",
        "protected": false
      },
      {
        "name": "master",
        "protected": false
      }
    ]
  },
  {
    "name": "rokehan",
    "ownerLogin": "test",
    "branch": [
      {
        "name": "master",
        "protected": false
      }
    ]
  },
  {
    "name": "sNews",
    "ownerLogin": "test",
    "branch": []
  },
  {
    "name": "Test--01",
    "ownerLogin": "test",
    "branch": [
      {
        "name": "master",
        "protected": false
      }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

请帮我解决这个问题。

Tho*_*olf 5

我没有坐在电脑旁,所以我无法检查编译器(我是在移动设备上写的)

但问题是您正在尝试序列化 a,Mono<List<T>>这意味着您正在尝试发送可能尚未解决的内容。您需要返回一个List<T>.

private Flux<MyResponse> getGitRepos(String userName) {
    return webClient.get()
                    .uri("/users/{userName}/repos", userName)
                    .exchangeToFlux(clientResponse -> clientResponse.bodyToFlux(GithubRepo.class))
                    .flatMap(github -> {
                        return webClient.get()
                                        .uri("/repos/{userName}/{branchName}/branches", userName, github.getBranch())
                                        .retrieve()
                                            .bodyToFlux(Branch.class)
                                        .collectList())
                                        .flatMap(branches -> {
                                            return Mono.just(new MyResponse(github, branches));
                                        });
        }
Run Code Online (Sandbox Code Playgroud)

这是我徒手写的,但你应该明白我的意思。有一个类针对 github api,另一个类针对您的 api,这样如果针对 github 的 api 发生变化,您就可以自由地更改您的 api。