在 Spring Webflux 中返回多个 Monos
Returning multiple Monos in Spring Webflux
我正在尝试使用 SpringBoot 2.0 和新的反应式 webFlux 库。我想知道如何 return 通过 none 阻塞 WebClient 向我的 Springboot API 的调用者发出的两次调用的结果。我的代码是:
@RequestMapping("/search")
public CombinedResults perfomSearch(@RequestParam final String searchTerm) {
Mono<SearchResponse> fasMono = searchService.getSearchResults(searchTerm, "fh");
Mono<SearchResponse> esMono = searchService.getSearchResults(searchTerm, "es");
CombinedResults combinedResults = new CombinedResults(fasMono, esMono);
return combinedResults;
}
CombinedResult 对象只是一个 POJO:
public class CombinedResults {
private Mono<SearchResponse> fasSearchResponse;
private Mono<SearchResponse> esSearchResponse;
public CombinedResults(final Mono<SearchResponse> fasSearchResponse, final Mono<SearchResponse> esSearchResponse) {
this.fasSearchResponse = fasSearchResponse;
this.esSearchResponse = esSearchResponse;
}
public Mono<SearchResponse> getFasSearchResponse() {
return fasSearchResponse;
}
public void setFasSearchResponse(final Mono<SearchResponse> fasSearchResponse) {
this.fasSearchResponse = fasSearchResponse;
}
public Mono<SearchResponse> getEsSearchResponse() {
return esSearchResponse;
}
public void setEsSearchResponse(final Mono<SearchResponse> esSearchResponse) {
this.esSearchResponse = esSearchResponse;
}
但是,如果我调用它,我得到的响应是
{
"fasSearchResponse": {
"scanAvailable": true
},
"esSearchResponse": {
"scanAvailable": true
}
}
而不是 SearchResponse 对象的内容。我觉得我可能遗漏了一个关于它应该如何工作的基本点!我的想法是,因为 WebClient none 阻塞,我可以触发对 Web 服务的两个调用,然后将它们组合起来,而不需要可完成的期货等?
我认为您应该 return 表示此操作响应的模型的对象的 Mono。假设 CombinedResults
是您的模型。这个 class 应该是这样的:
public class CombinedResults {
private SearchResponse fasSearchResponse;
private SearchResponse esSearchResponse;
public CombinedResults(final SearchResponse fasSearchResponse, final SearchResponse esSearchResponse) {
this.fasSearchResponse = fasSearchResponse;
this.esSearchResponse = esSearchResponse;
}
//... getters AND/OR setters
}
然后,在您的控制器上执行如下操作:
@RequestMapping("/search")
public Mono<CombinedResults> perfomSearch(@RequestParam final String searchTerm) {
Mono<SearchResponse> fasMono = searchService.getSearchResults(searchTerm, "fh");
Mono<SearchResponse> esMono = searchService.getSearchResults(searchTerm, "es");
Mono<CombinedResults> combinedResults =
fasMono
.flatMap(fh -> esMono.map(es -> new CombinedResults(fh, es)));
return combinedResults;
}
通过这种方式,您可以 return 创建一个包含您想要的响应的 Mono 对象。当两个 Mono 都发出项目时,fasMono.flatMap
和 esMono.map
的操作链构建 CombinedResults
。当尝试将两个 Monos 合二为一时,这种组合相当常见。我认为您也可以使用 zip
运算符来加入 Monos。
所有这些都与 WebClient 无关。如果您的 getSearchResults
仅执行 async-nonblocking 操作,那么一切都是 async-nonblocking.
Spring WebFlux 不支持嵌套的反应类型。
你应该有这样的东西:
Mono<SearchResponse> fasMono = searchService.getSearchResults(searchTerm, "fh");
Mono<SearchResponse> esMono = searchService.getSearchResults(searchTerm, "es");
Mono<CombinedResults> results = fasMono.zipWith(esMono,
(fas, es) -> {return new CombinedResults(fas, es);});
我正在尝试使用 SpringBoot 2.0 和新的反应式 webFlux 库。我想知道如何 return 通过 none 阻塞 WebClient 向我的 Springboot API 的调用者发出的两次调用的结果。我的代码是:
@RequestMapping("/search")
public CombinedResults perfomSearch(@RequestParam final String searchTerm) {
Mono<SearchResponse> fasMono = searchService.getSearchResults(searchTerm, "fh");
Mono<SearchResponse> esMono = searchService.getSearchResults(searchTerm, "es");
CombinedResults combinedResults = new CombinedResults(fasMono, esMono);
return combinedResults;
}
CombinedResult 对象只是一个 POJO:
public class CombinedResults {
private Mono<SearchResponse> fasSearchResponse;
private Mono<SearchResponse> esSearchResponse;
public CombinedResults(final Mono<SearchResponse> fasSearchResponse, final Mono<SearchResponse> esSearchResponse) {
this.fasSearchResponse = fasSearchResponse;
this.esSearchResponse = esSearchResponse;
}
public Mono<SearchResponse> getFasSearchResponse() {
return fasSearchResponse;
}
public void setFasSearchResponse(final Mono<SearchResponse> fasSearchResponse) {
this.fasSearchResponse = fasSearchResponse;
}
public Mono<SearchResponse> getEsSearchResponse() {
return esSearchResponse;
}
public void setEsSearchResponse(final Mono<SearchResponse> esSearchResponse) {
this.esSearchResponse = esSearchResponse;
}
但是,如果我调用它,我得到的响应是
{
"fasSearchResponse": {
"scanAvailable": true
},
"esSearchResponse": {
"scanAvailable": true
}
}
而不是 SearchResponse 对象的内容。我觉得我可能遗漏了一个关于它应该如何工作的基本点!我的想法是,因为 WebClient none 阻塞,我可以触发对 Web 服务的两个调用,然后将它们组合起来,而不需要可完成的期货等?
我认为您应该 return 表示此操作响应的模型的对象的 Mono。假设 CombinedResults
是您的模型。这个 class 应该是这样的:
public class CombinedResults {
private SearchResponse fasSearchResponse;
private SearchResponse esSearchResponse;
public CombinedResults(final SearchResponse fasSearchResponse, final SearchResponse esSearchResponse) {
this.fasSearchResponse = fasSearchResponse;
this.esSearchResponse = esSearchResponse;
}
//... getters AND/OR setters
}
然后,在您的控制器上执行如下操作:
@RequestMapping("/search")
public Mono<CombinedResults> perfomSearch(@RequestParam final String searchTerm) {
Mono<SearchResponse> fasMono = searchService.getSearchResults(searchTerm, "fh");
Mono<SearchResponse> esMono = searchService.getSearchResults(searchTerm, "es");
Mono<CombinedResults> combinedResults =
fasMono
.flatMap(fh -> esMono.map(es -> new CombinedResults(fh, es)));
return combinedResults;
}
通过这种方式,您可以 return 创建一个包含您想要的响应的 Mono 对象。当两个 Mono 都发出项目时,fasMono.flatMap
和 esMono.map
的操作链构建 CombinedResults
。当尝试将两个 Monos 合二为一时,这种组合相当常见。我认为您也可以使用 zip
运算符来加入 Monos。
所有这些都与 WebClient 无关。如果您的 getSearchResults
仅执行 async-nonblocking 操作,那么一切都是 async-nonblocking.
Spring WebFlux 不支持嵌套的反应类型。 你应该有这样的东西:
Mono<SearchResponse> fasMono = searchService.getSearchResults(searchTerm, "fh");
Mono<SearchResponse> esMono = searchService.getSearchResults(searchTerm, "es");
Mono<CombinedResults> results = fasMono.zipWith(esMono,
(fas, es) -> {return new CombinedResults(fas, es);});