0

In my spring-boot springboot service class, I have created the following code which is not working as desired:

Service class:

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

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

Please someone help me on converting the list of json values to put it into arrayList

Json

[
{
"id:"123abc"
},
{
"id:"123abc"
}
] 
groot
  • 57
  • 3
  • 12

2 Answers2

1

Why is the code not working as desired

mWorkspace is a publisher of one or many items of type Workspace.

Calling newmWorkspace.blockLast() will get a Workspace from that Publisher:
which is an object of type: Workspace and not of type ArrayList<String>.

That's why : Type mismatch: cannot convert from Workspace to ArrayList<String>

Converting from Flux to an ArrayList

First of all, in reactive programming, a Flux is not meant to be blocked, the blockxxx methods are made for testing purposes. If you find yourself using them, then you may not need reactive logic.

In your service, you shall try this :

//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();

Just in case you want to convert a JSON String to a POJO:

String responseAsjsonString = "[{\"id\": \"123abc\"},{\"id\": \"123cba\"}] ";
Workspace[] workspaces = new ObjectMapper().readValue(responseAsjsonString, Workspace[].class);
Philippe Simo
  • 1,353
  • 1
  • 15
  • 28
  • Actually i should return the values received from this method to another method as body How can i do that i tried to return mWorkspace its giving error. – groot Mar 25 '21 at 09:48
  • Then return mWorkspace (which is a Flux) instead of an arrayList - from the your method, the apply the map operation on the returned Flux in the other method. Meaning you arrayList will be fed in the other method. – Philippe Simo Mar 25 '21 at 14:10
0

You would usually want to avoid blocking in a non-blocking application. However, if you are just integrating from blocking to non-blocking and doing so step-by-step (unless you are not mixing blocking and non-blocking in your production code), or using a servlet stack app but want to only use the WebFlux client, it should be fine.

With that being said, a Flux is a Publisher that represents an asynchronous sequence of 1..n emitted items. When you do a blockLast you wait until the last signal completes, which resolves to a Workspace object.

You want to collect each resolved item to a list and return that. For this purpose, there is a useful method called collectList, which does this job without blocking the stream. You can then block the Mono<List<Workspace>> returned by this method to retrieve the list.

So this should give you the result you want:

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

If you must use a blocking call in the reactive stack, to avoid blocking the event loop, you should subscribe to it on a different scheduler. For the I/O purposes, you should use the boundedElastic Scheduler. You almost never want to call block on a reactive stack, instead subscribe to it. Or better let WebFlux to handle the subscription by returning the publisher from your controller (or Handler).

ProgrammerPotato
  • 505
  • 1
  • 4
  • 11