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

SpringBoot WebFlux大文件上传异常:仅支持500KB以下文件

问题原因与解决方案

核心原因

  1. 错误读取分片数据:attachment.content()返回Flux<DataBuffer>,大文件会被拆分为多个DataBuffer分片传输,awaitFirst()仅获取了第一个分片(默认大小1024字节),导致仅读取部分内容。
  2. 配置不匹配:WebFlux基于Reactor Netty而非Servlet容器,spring.servlet.multipart配置对WebFlux无效。

解决方案

1. 正确读取完整文件内容

收集所有DataBuffer分片并合并为完整字节数组,修改控制器代码:

@RestController
@RequestMapping("/emailFile")
class EmailController {
    val logger = LoggerFactory.getLogger(this::class.java)

    @PostMapping("/upload", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    suspend fun uploadFile(
        @RequestPart("attachment") attachment: FilePart,
        @RequestPart("message") message: String
    ): ResponseEntity<String> {
        // 收集所有分片并合并
        val dataBuffers = attachment.content().collectList().awaitSingle()
        val totalSize = dataBuffers.sumOf { it.readableByteCount() }
        val mergedBuffer = ByteBuffer.allocate(totalSize)
        
        dataBuffers.forEach { buffer ->
            mergedBuffer.put(buffer.asByteBuffer())
            buffer.release() // 释放资源避免内存泄漏
        }
        mergedBuffer.flip()
        
        logger.debug(mergedBuffer.array().size.toString())
        File("testfilespring.png").writeBytes(mergedBuffer.array())

        return ResponseEntity(message, HttpStatus.ACCEPTED)
    }
}

2. 配置WebFlux专属的上传限制

替换原Servlet配置,使用WebFlux参数:

spring:
  codec:
    max-in-memory-size: 10MB # 内存中允许的最大文件大小,超过则写入临时文件
  webflux:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

优化方案(推荐)

处理大文件时,直接使用transferTo写入磁盘,无需手动处理字节,自动分片合并和资源释放:

@RestController
@RequestMapping("/emailFile")
class EmailController {
    val logger = LoggerFactory.getLogger(this::class.java)

    @PostMapping("/upload", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    suspend fun uploadFile(
        @RequestPart("attachment") attachment: FilePart,
        @RequestPart("message") message: String
    ): ResponseEntity<String> {
        // 直接写入文件
        attachment.transferTo(File("testfilespring.png")).awaitSingle()
        logger.debug("文件上传完成")

        return ResponseEntity(message, HttpStatus.ACCEPTED)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:45:37