【问题标题】:Reactive way to read and parse file from resources using WebFlux?使用 WebFlux 从资源中读取和解析文件的反应方式?
【发布时间】:2020-07-23 03:17:36
【问题描述】:

我想知道从资源中读取、解析和提供文件的正确方法是什么。

目前,我做这样的事情:

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() }

我注意到 Netty 中的 JsonObjectDecoder 类,但我不知道是否可以应用于我的用例。

那么读取/解析资源文件的反应方式是什么?

【问题讨论】:

  • 所有 i/o 操作都是阻塞的。文件的读取应包含在Mono#fromCallable 中并放置在它自己的scheduler 上,这是有界的以避免线程饥饿。您可以在此处阅读有关阻止呼叫的更多信息projectreactor.io/docs/core/release/reference/…

标签: json kotlin spring-webflux project-reactor


【解决方案1】:

您可以查看Flux.using here 进行文件读取。

由于你使用的是Spring框架,你也可以看看DataBufferUtils

DataBufferUtils 使用AsynchronousFileChannel 读取文件,并且在订阅者读取/取消文件后,它还在内部使用Flux.using 释放文件。

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


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

【讨论】:

    【解决方案2】:

    在扩展@vins 答案后,我得出了以下解决方案:

    Jackson2JsonDecoder()
        .decodeToMono(
            DataBufferUtils.read(
                DefaultResourceLoader()
                    .getResource("$fileName.json"),
                DefaultDataBufferFactory(),
                4096
            ),
            ResolvableType.forClass(JsonModel::class.java), null, null
        )
        .map { it as JsonModel }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-08
      • 2014-01-11
      • 2016-06-17
      • 2021-08-11
      • 2018-03-29
      • 2021-11-21
      相关资源
      最近更新 更多