3

I wonder what is the correct way to read, parse and serve a file from resources.

Currently, I do something like this:

fun getFile(request: ServerRequest): Mono<ServerResponse> {
    val parsedJson =
        objectMapper.readValue(readFile("fileName.json"), JsonModel::class.java)

    // modify parsed json

    return ok().contentType(APPLICATION_JSON).bodyValue(parsedJson)
}

private fun readFile(fileName: String) =
    DefaultResourceLoader()
        .getResource(fileName)
        .inputStream.bufferedReader().use { it.readText() }

I've noticed JsonObjectDecoder class in Netty, but I don't know if can be applied to my use case.

What is the reactive way to do read/parse resource file then?

1
  • All i/o operations are blocking. The reading of the file should by wrapped in a Mono#fromCallable and placed on its own scheduler thats bounded to avoid thread starvation. You can read more about blocking calls here projectreactor.io/docs/core/release/reference/… Commented Apr 10, 2020 at 15:00

2 Answers 2

4

After expanding @vins answer, I've came to following solution:

Jackson2JsonDecoder()
    .decodeToMono(
        DataBufferUtils.read(
            DefaultResourceLoader()
                .getResource("$fileName.json"),
            DefaultDataBufferFactory(),
            4096
        ),
        ResolvableType.forClass(JsonModel::class.java), null, null
    )
    .map { it as JsonModel }
Sign up to request clarification or add additional context in comments.

Comments

2

You can take a look at Flux.using here for file read.

As you are using Spring framework, You can also take a look at the DataBufferUtils.

This DataBufferUtils uses AsynchronousFileChannel to read the file and it also internally uses Flux.using to release the file once the file is read / cancelled by the subscriber.

@Value("classpath:somefile.json")
private Resource resource;


@GetMapping("/resource")
public Flux<DataBuffer> serve(){
   return DataBufferUtils.read(
            this.resource,
            new DefaultDataBufferFactory(),
            4096
    );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.