0

The following function will retrieve a List of String. During the merge process, rather then print the output I would like to write the output to a CSV file.

List<Mono<Device>> list1 = page.get().map(device -> webClient.post()
                .uri(uri)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .body(Mono.just("{ \"mac\": \"" + device.getData()  ), String.class)
                .attributes(ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("xxxx"))
                .retrieve()
                .bodyToMono(Device.class)).collect(Collectors.toList());

        Flux<Device> mergedMonos = Flux.fromIterable(list1).flatMapSequential(Function.identity());
        mergedMonos.doOnNext(System.out::println)
                .subscribe();


public class Device {
 @JsonProperty("ip")
 private String ip;
 @JsonProperty("macAddress")
 private String macAddress;
 @JsonProperty("vendor")
 private String vendor;

How can I write the Device (Json) data to a CSV file ?

Thank you

angus
  • 3,210
  • 10
  • 41
  • 71

1 Answers1

0

Checkout Converting JSON to CSV in Java

You can utilize the jackson library to convert a java object to csv. In dependencies add:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-csv</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>

Then in code:

ObjectMapper mapper = new ObjectMapper();
Flux<Device> mergedMonos = 
Flux.fromIterable(list1).flatMapSequential(Function.identity());
List<JsonNode> nodes = mergedMonos
    .collectList()
    .map(mapper::valueToTree)
    .subscribe(list -> {
        Builder csvSchemaBuilder = CsvSchema.builder();
        JsonNode firstObject = list.elements().next();
        firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} );
        CsvSchema csvSchema = csvSchemaBuilder.build().withHeader();
        CsvMapper csvMapper = new CsvMapper();
        csvMapper.writerFor(JsonNode.class)
          .with(csvSchema)
          .writeValue(new File("output.csv"), list);
    });
Tahir Mustafa
  • 323
  • 1
  • 10
  • Thank you Tahir. Why there is a need for using twice valueToTree ? – angus Apr 07 '21 at 14:43
  • @angus First convers an individual device object to a tree, and then the list of trees to a tree. Looking again at the code, I see the first valueToTree is redundant, since it will be covered in the second. – Tahir Mustafa Apr 08 '21 at 06:27