You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot整合Jersey REST API返回Zip文件无法获取文件名问题

问题分析与解决方案

核心问题在于:你先向响应输出流写入了文件内容,之后才设置响应头。HTTP协议要求响应头必须在响应体之前发送,一旦开始写入响应体(文件流),服务器容器会自动发送已设置的响应头,后续修改的Content-Disposition等头信息根本不会生效。

修正后的代码

@Context
lateinit var httpServletResponse: HttpServletResponse

@POST
@Path("/getRecord")
@Produces("application/zip", MediaType.APPLICATION_JSON)
fun getRecord(@RequestBody recordIdentification: RecordIdentificationRequest) {
    val compositeRecord: CompositeRecord = service.getRecordFromRequest(recordIdentification)
    val tmpFile: File? = service.getRecordZip(compositeRecord)

    tmpFile?.let { file ->
        // 1. 优先设置所有响应头和状态码
        httpServletResponse.status = HttpStatus.OK.value()
        httpServletResponse.contentType = "application/zip"
        httpServletResponse.setHeader(HttpHeaders.CONTENT_LENGTH, file.length().toString())
        
        // 指定UTF-8编码避免中文/特殊字符文件名乱码
        val contentDisposition = ContentDisposition.attachment()
                .filename(file.name, StandardCharsets.UTF_8)
                .build()
        httpServletResponse.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString())

        // 2. 写入文件流,用use函数自动关闭输入流防止资源泄漏
        Files.newInputStream(file.toPath()).use { inputStream ->
            inputStream.transferTo(httpServletResponse.outputStream)
        }

        // 3. 完成流操作后刷新并关闭输出流
        httpServletResponse.outputStream.flush()
        httpServletResponse.outputStream.close()
    } ?: run {
        // 处理文件不存在的异常场景
        httpServletResponse.status = HttpStatus.NOT_FOUND.value()
        httpServletResponse.contentType = MediaType.APPLICATION_JSON_VALUE
        httpServletResponse.writer.write("{\"error\": \"Record zip file not found\"}")
    }
}

关键优化点

  • 调整执行顺序:必须先设置响应头,再写入响应体,符合HTTP协议规范
  • 文件名编码处理:给filename指定UTF-8编码,避免客户端显示乱码
  • 资源自动管理:用Kotlin的use函数自动关闭输入流,避免资源泄漏
  • 异常场景处理:增加文件不存在时的错误响应,提升接口健壮性

内容的提问来源于stack exchange,提问作者abdel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:47:46