spring webflux webclient响应将字符串列表转换为字符串
答复:spring webflux webclient响应将字符串列表转换为字符串,spring,spring-boot,java-8,mono,spring-webflux,Spring,Spring Boot,Java 8,Mono,Spring Webflux,答复: [ { "version": "1.0", "content": [ "12345", "67076", "123462", "604340", "1331999", "1332608", "1785581", ] } ] 代码: Mono-mp=webClient.get().uri(accountMgmtURI) .retrieve() .bodyToMono(地图类) .flatMap(trans->{
[
{
"version": "1.0",
"content": [
"12345",
"67076",
"123462",
"604340",
"1331999",
"1332608",
"1785581",
]
}
]
代码:
Mono-mp=webClient.get().uri(accountMgmtURI)
.retrieve()
.bodyToMono(地图类)
.flatMap(trans->{
列表内容=(列表)trans.get(“内容”);
System.out.println(“内容::”+内容);
返回Mono.just(content);
});
System.out.println(“内容:”+mp.toString());
String sites=mp.toString();
请使用现成的解决方案。您不应该使用List content=(List)trans.get(“content”)
。Java是一种强大的类型化语言,所以要为类型创建类。和框架一样,spring处理类和对象
在这种情况下:
public class VersionedDataResponse {
private List<VersionedData> versionedDataList;
}
....
public class VersionedData {
private String version;
private List<String> content;
}
public类versionedataresponse{
私有列表版本数据列表;
}
....
公共类版本数据{
私有字符串版本;
私有列表内容;
}
spring将在bodyToMono(VersionedDataResponse.class)转换它。第一个问题是,您使用的API不是返回单个对象,而是返回一个对象数组,用方括号(
[]
)表示
这意味着您至少应该重构代码以使用bodyToFlux()
而不是bodyToMono()
:
客户端
.get()
.retrieve()
//bodyToFlux()代替bodyToMono(
.bodyToFlux(地图类)
// ...
第二个问题是,在这种情况下,使用
Map
并不容易,因为由于无法通过任何泛型,您必须始终强制转换所有内容。使用适当的类会使事情变得更容易。例如,您可以编写以下类:
公共类版本内容{
私有字符串版本;
私有列表内容;
//TODO:getter+setter
}
并将代码更改为:
客户端
.get()
.retrieve()
.bodyToFlux(版本内容类)
.map(VersionContent::getContent)
.flatMap(通量::fromIterable)
// ...
这段代码将检索每个对象的内容,并flatMap
it,以便分别发出每个单独的值
现在,
content
数组中的每一项都将单独发布。这就引出了第三个问题,即您没有连接字符串
要浓缩项目,可以使用reduce()
运算符:
客户端
.get()
.retrieve()
.bodyToFlux(版本内容类)
.map(VersionContent::getContent)
.flatMap(通量::fromIterable)
//reduce()可用于将所有单个项合并为单个项
.reduce((站点,站点)->sites+“|”+站点)
// ...
最后一个问题是,您使用的是
toString()
,这是行不通的。反应式编程的一个关键方面是,所有事情都是异步进行的。这意味着,如果您尝试在主线程中对数据执行任何操作,都不会发生任何事情
此外,像Mono
和Flux
这样的出版商的另一个特点是他们是懒惰的。没有适当的订阅,什么事情都不会发生
解决方案是正确地subscribe()
获取您的值,例如:
客户端
.get()
.retrieve()
.bodyToFlux(版本内容类)
.map(VersionContent::getContent)
.flatMap(通量::fromIterable)
.reduce((站点,站点)->sites+“|”+站点)
.subscribe(System.out::println);
对于您的示例,上面的代码会将以下内容打印到控制台:
12345|67076|123462|604390|1331999|1332608|1785581
请注意,这也意味着您要对这些站点执行的每个操作都应该异步完成
如果您不想异步工作,可以使用block()
操作符,如下所示:
String sites=client
.get()
.retrieve()
.bodyToFlux(版本内容类)
.map(VersionContent::getContent)
.flatMap(通量::fromIterable)
.reduce((站点,站点)->sites+“|”+站点)
.block();
Mono-mp=webClient.get().uri(accountMgmtURI).retrieve().bodytomino(Map.class).flatMap(trans->{List-content=(List)trans.get(“content”);System.out.println(“content::”+content);返回Mono.just(content);});System.out.println(“内容::”+mp.toString()););String sites=mp.toString();请发布您的预期输出并解释您面临的问题响应值不在“sites”中,我希望以管道(|)分隔格式响应,如:sites:“12345 | 67076 | 776788…”。。。。。。。。"... 但是,在调试模式下,我无法获取任何值,在我出错的情况下,您试图映射到bodytomino(map.class)
,但是您得到的响应是一个元素数组。我认为您无法正确地将这些映射到Mono
。如果要在上面的示例中使用block,您能解释一下为什么我们不应该在webclient中使用flux吗?我以为rest模板已经过时了(好几年之后),还有什么选择呢?@octo carrot我会继续使用RestTemplate
,但这可能不是一个好的选择。我删除了提到它不应用于阻止呼叫的段落。
12345|67076|123462|604390|1331999|1332608|1785581