如何将 Flux<pojo> 转换为 ArrayList<String>

Posted

技术标签:

【中文标题】如何将 Flux<pojo> 转换为 ArrayList<String>【英文标题】:how to convert Flux<pojo> to ArrayList<String> 【发布时间】:2021-06-21 09:24:04 【问题描述】:

在我的 spring-boot springboot 服务类中,我创建了以下无法按预期工作的代码:

服务类:

Flux<Workspace> mWorkspace = webClient.get().uri(WORKSPACEID)
.retrieve().bodyToFlux(Workspace.class);

ArrayList<String> newmWorkspace = new ArrayList();
newmWorkspace = mWorkspace.blockLast();
return newmWorkspace;

请有人帮助我将 json 值列表转换为 arrayList

json

[

"id:"123abc"
,

"id:"123abc"

] 

【问题讨论】:

你有什么错误吗? 是这样,类型不匹配:无法从 Workspace 转换为 ArrayList 【参考方案1】:

为什么代码不能按预期工作

mWorkspace 是 Workspace 类型的一个或多个项目的发布者。

调用 newmWorkspace.blockLast() 将从该发布者那里获得一个工作区: 这是一个类型的对象: Workspace,而不是ArrayList&lt;String&gt;

这就是为什么: Type mismatch: cannot convert from Workspace to ArrayList&lt;String&gt;

从 Flux 转换为 ArrayList

首先,在响应式编程中,Flux 并不意味着被阻塞,blockxxx 方法是为了测试目的而设计的。如果您发现自己在使用它们,那么您可能不需要响应式逻辑。

在你的服务中,你应该试试这个:

//initialize the list
ArrayList<String> newmWorkspace = new ArrayList<>();

Flux<Workspace> mWorkspace = webClient.get().uri(WORKSPACEID)
.retrieve().bodyToFlux(Workspace.class)
.map(workspace -> 
       //feed the list
       newmWorkspace.add(workspace.getId());
       return workspace;
);

 
//this line will trigger the publication of items, hence feeding the list
mWorkspace.subscribe();

以防万一您想将 JSON 字符串转换为 POJO:

String responseAsjsonString = "[\"id\": \"123abc\",\"id\": \"123cba\"] ";
Workspace[] workspaces = new ObjectMapper().readValue(responseAsjsonString, Workspace[].class);

【讨论】:

实际上我应该将从这个方法接收到的值返回给另一个方法作为 body 我该怎么做我试图返回 mWorkspace 它的错误。 然后返回 mWorkspace(这是一个 Flux)而不是 arrayList - 从您的方法中,在另一个方法中对返回的 Flux 应用映射操作。这意味着您的 arrayList 将在其他方法中提供。【参考方案2】:

您通常希望避免在非阻塞应用程序中阻塞。但是,如果您只是从阻塞集成到非阻塞并逐步进行(除非您没有在生产代码中混合阻塞和非阻塞),或者使用 servlet 堆栈应用程序但只想使用WebFlux 客户端,应该没问题。

话虽如此,Flux 是一个 Publisher,它表示 1..n 发出的项目的异步序列。当您执行blockLast 时,您会等到最后一个信号完成,它会解析为一个 Workspace 对象。

您希望将每个已解决的项目收集到一个列表中并将其返回。为此,有一个名为collectList 的有用方法,它可以在不阻塞流的情况下完成这项工作。然后您可以阻止此方法返回的Mono&lt;List&lt;Workspace&gt;&gt; 以检索列表。

所以这应该会给你想要的结果:

List<Workspace> workspaceList = workspaceFlux.collectList().block();

如果您必须在反应堆栈中使用阻塞调用,以避免阻塞事件循环,您应该在不同的调度程序上订阅它。出于 I/O 目的,您应该使用 boundedElastic 调度程序。你几乎不想在反应式堆栈上调用block,而是订阅它。或者最好让 WebFlux 通过从控制器(或处理程序)返回发布者来处理订阅。

【讨论】:

以上是关于如何将 Flux<pojo> 转换为 ArrayList<String>的主要内容,如果未能解决你的问题,请参考以下文章

如何正确读取 Flux<DataBuffer> 并将其转换为单个 inputStream

将 Map<String, String> 转换为 POJO

如何在 Java Stream 中将 POJO 的列表转换为 Map<String,List>?

Jpa 从POJO 转换成表

无法从 Flux<PortCall> 转换为 Mono<?扩展对象>

spring webflux Flux<DataBuffer> 转换为 InputStream