Search code examples
javaspringspring-bootspring-webclient

How to use Flux to write Json Pojo to a CSV


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


Solution

  • 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);
        });