Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
spring webflux webclient响应将字符串列表转换为字符串_Spring_Spring Boot_Java 8_Mono_Spring Webflux - Fatal编程技术网

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