简体   繁体   中英

Spring Reactive manipulating Object before returning it to Client

I have to call a URL which returns this JSON output

{
    "zonesList": [
        "zone1",
        "zone2",
        "zone5",
        "zone4"
    ]
}

My goal is to return a POJO with Boolean values like

zone1: true Zone2: true zone3: false (as zone3 is not in the output)

I created 2 pojo's like this

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ZonesList {
    public ZoneActiveContentResponseModel zonesList;
}

and

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ZoneActiveContentResponseModel  {

   
    public Boolean zone1 = false;
    public Boolean zone2 = false;
    public Boolean zone3 = false;
    public Boolean zone4 = false;
    public Boolean zone5 = false;
}

I wanted to return Mono but I am not sure how to return it, this is what i have now

Mono<ZonesList> zoneList = webClient
                .get()
                .uri(apiPath)
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToMono(ZonesList.class)
                .onErrorResume(throwable -> {
                    log.error("Received error response from GET zone fragment Api [{}]", throwable);
                    ZoneActiveContentResponseModel errorModel = new ZoneActiveContentResponseModel();
                  //  errorModel.setErrors(prepareErrorObject(throwable));
                  //  return Mono.just(errorModel);
                    return null;
                });

So my question how can i manipulate the output from webclient and return a new Object?

First thing you have this response

{
    "zonesList": [
        "zone1",
        "zone2",
        "zone5",
        "zone4"
    ]
}

So this can be mapped in the following custom object from Jackson

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class ZonesList {
  
  private List<String> zonesList;

}

Then you can use this one to map it to the other object that you actually want to return. The one you have defined

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ZoneActiveContentResponseModel  {

   
    public Boolean zone1 = false;
    public Boolean zone2 = false;
    public Boolean zone3 = false;
    public Boolean zone4 = false;
    public Boolean zone5 = false;
}

Then you use .map to convert the response you have received to the one you want to give back from your controller

Mono<ZonesList> zoneList = webClient

                .get()
                .uri(apiPath)
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToMono(ZonesList.class)
                .map (el -> 
new ZoneActiveContentResponseModel( el.getZonesList.contains("zone1"),
                                    el.getZonesList.contains("zone2"),
                                    el.getZonesList.contains("zone3"),
                                    el.getZonesList.contains("zone4"),
                                    el.getZonesList.contains("zone5")) )
                .onErrorResume(throwable -> {
                    log.error("Received error response from GET zone fragment Api [{}]", throwable);
                    ZoneActiveContentResponseModel errorModel = new ZoneActiveContentResponseModel();
                  //  errorModel.setErrors(prepareErrorObject(throwable));
                  //  return Mono.just(errorModel);
                    return null;
                });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM