如何使用Content-Type将KotlinFlow作为非流JSON数据返回:在Spring Framework 6中使用application/json?

wlwcrazw  于 2023-08-02  发布在  Spring
关注(0)|答案(1)|浏览(79)

控制器方法接口:

@RequestMapping(
        method = [RequestMethod.GET],
        value = ["/list"],
        produces = ["application/json"]
)
suspend fun list(): ResponseEntity<Flow<MyClass>>

字符串
控制器方法实现:

override suspend fun list(): ResponseEntity<Flow<MyClass>> {
    val list: List<MyClass> = service.getMyClass()
    val flow = flow { emitAll(list.asFlow()) }
    return ResponseEntity.ok(flow)
}


在升级到Sping Boot 3(Spring 6)之前,该端点作为非流端点工作得很好。
升级后,它会产生一个错误:

Unexpected end-of-input: expected close marker for Array


我找到了这个页面:
https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x
这是一条线:

Spring WebFlux

Flux return values for non-streaming media types (no longer collected to List before written).


所以我明白新版本的Spring试图流我的数据,我有Content-Type: application/json并不重要。
问题是:我如何恢复旧行为?
我的前端目前需要它。
我看到这个答案https://stackoverflow.com/a/61146874/22210497描述了旧的行为。
现在这段代码已经从Spring代码库中消失了。
可能是在这个问题上的想法-https://github.com/spring-projects/spring-framework/issues/28398

xdnvmnnf

xdnvmnnf1#

所以可能我通过从Spring 5版本中获取代码来管理它:

class CustomJackson2JsonEncoder(mapper: ObjectMapper) : Jackson2JsonEncoder(mapper, *arrayOf()) {

    override fun encode(
        inputStream: Publisher<*>,
        bufferFactory: DataBufferFactory,
        elementType: ResolvableType,
        mimeType: MimeType?,
        hints: MutableMap<String, *>?
    ): Flux<DataBuffer> {
        if (inputStream is Mono || getStreamingMediaTypeSeparator(mimeType) != null) {
            return super.encode(inputStream, bufferFactory, elementType, mimeType, hints)
        }
        val listType = ResolvableType.forClassWithGenerics(List::class.java, elementType)
        return Flux
            .from(inputStream)
            .collectList()
            .map { encodeValue(it, bufferFactory, listType, mimeType, hints) }
            .flux()
    }

}

@Configuration
class WebFluxConfig(private val objectMapper: ObjectMapper) : WebFluxConfigurer {

    override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
        configurer
            .defaultCodecs()
            .jackson2JsonEncoder(CustomJackson2JsonEncoder(objectMapper))
    }

}

字符串
首先,这段代码检查我们是否有Mono或流媒体类型。
如果是,则调用超类的encode方法。
如果否,则它在写入之前收集FluxList
不确定它是否正确,哪里可以有一些警告,但它的工作...

相关问题