微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Jackson ObjectWriter 只从流中写入第一个条目

如何解决Jackson ObjectWriter 只从流中写入第一个条目

我想创建一个 Spring Boot 控制器,它使用来自流的数据创建一个 CSV 文件。我使用 Jackson CSV (jackson-dataformat-csv 2.12.1) 将数据流从数据库写入 streamingresponsebody

为了简单起见,我用包含 1,2,3 的列表替换了来自数据库的实际数据。我想要一个看起来像这样的 CSV 文件

1
2
3

但它只包含第一个条目 (1)。有人可以帮我找出问题所在吗?

请注意,我不想在服务器上的某处创建文件,我想将内容直接流式传输给用户

我的代码如下:

import com.fasterxml.jackson.dataformat.csv.CsvMapper
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.mvc.method.annotation.streamingresponsebody
import javax.servlet.http.HttpServletResponse

@RestController
@RequestMapping(value = ["/test"],produces = [MediaType.TEXT_HTML_VALUE])
class TestController {

    @GetMapping("/download",produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
    fun download(response: HttpServletResponse): ResponseEntity<streamingresponsebody>? {
        response.setHeader("Content-disposition","attachment;filename=download.csv")
        response.status = HttpServletResponse.SC_OK

        val mapper = CsvMapper()
        val schema = mapper.schemaFor(Int::class.java)
        val writer = mapper.writer(schema)
        val input = listof(1,3).stream()

        val stream = streamingresponsebody { outputStream ->
            input.forEach { entity ->
                writer.writeValue(outputStream,entity)
            }
        }

        return ResponseEntity
            .ok()
            .header("Content-disposition","attachment;filename=download.csv")
            .body(stream)
    }
}

解决方法

在 Andriy 评论的帮助下,我找到了原因和解决方案。 Jackson 在完成写入后关闭流,请参阅:ObjectMapper._writeValueAndClose

要更改此行为,您必须像这样将 JsonGenerator.Feature.AUTO_CLOSE_TARGET 设置为 false:

val jsonFactory = CsvFactory().configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET,false)
val mapper = ObjectMapper(jsonFactory)
val writer = mapper.writer(CsvMapper().schemaFor(Int::class.java))

注意AUTO_CLOSE_TARGET 没有 CsvGenerator 选项,但使用 JsonGenerator 设置也适用于 CsvFactory

,

在您的代码中写入流时没有看到指定的列格式化程序。您可以尝试以下操作吗:-

    CsvMapper mapper = new CsvMapper();
    CsvSchema schema = mapper.schemaFor(Dymmy.class);
    schema = schema.withColumnSeparator('\t');

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。