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

Spring WebFlux Kotlin文件上传报HttpMediaTypeNotSupportedException排查

Spring WebFlux(Kotlin+Spring Boot)文件上传异常:HttpMediaTypeNotSupportedException 排查

问题场景

在基于Kotlin和Spring Boot的Spring WebFlux应用中实现文件上传时,已配置控制器处理multipart文件上传,但仍收到HttpMediaTypeNotSupportedException异常,提示信息:

Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'image/jpeg' is not supported]

现有配置

1. 控制器代码

@RestController
@Validated
class S3Controller {
    private val logger = LoggerFactory.getLogger(S3Controller::class.java)

    @Autowired
    private lateinit var s3: S3Service

    companion object {
        const val UPLOAD_FILE = "/uploadFile"
    }

    @Value("\${minio.buckets.kyc-bucket-name}")
    private val portfoliosBucket: String = ""

    @PostMapping(UPLOAD_FILE, consumes = ["multipart/form-data", MediaType.ALL_VALUE])
    suspend fun uploadFile(@RequestPart("file") file: FilePart): ResponseEntity<String> {
        logger.info("Received file: ${file.filename()} for upload")
        return try {
            val fileName = file.filename()
            s3.upload(
                bucket = portfoliosBucket,
                fileName = fileName,
                folder = "portfolios",
                part = file
            )
            logger.info("File uploaded successfully: $fileName")
            ResponseEntity.ok("File uploaded successfully: $fileName")
        } catch (e: Exception) {
            logger.error("Failed to upload file: ${e.message}", e)
            ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to upload file: ${e.message}")
        }
    }
}

2. 应用配置(application.yml)

spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 10MB

疑问解答

1. 为什么应用会拒绝image/jpeg类型的内容?

核心原因有两点:

  • 配置节点错误:你使用了spring.servlet.multipart配置,但Spring WebFlux属于非Servlet栈,该配置对WebFlux完全无效,导致multipart请求的处理逻辑未被正确初始化,无法解析文件part的Content-Type。
  • consumes参数逻辑混淆:@PostMapping的consumes是指定整个请求的顶层Content-Type,而非单个文件part的类型。你同时指定multipart/form-data和MediaType.ALL_VALUE会干扰Spring的请求匹配逻辑,当客户端发送multipart/form-data类型的请求时,Spring无法正确识别文件part的合法类型,最终抛出异常。

2. 需要检查哪些额外配置以确保文件上传被正确处理?

  • 替换为WebFlux专属的multipart配置:删除spring.servlet.multipart节点,改用WebFlux的配置项:
    spring:
      webflux:
        multipart:
          enabled: true
          max-file-size: 10MB
          max-request-size: 10MB
      codec:
        max-in-memory-size: 10MB # 控制内存中处理的文件大小,超出会自动写入临时文件
    
  • 修正控制器的consumes配置:仅保留multipart/form-data,因为文件上传请求的顶层Content-Type必须为该值:
    @PostMapping(UPLOAD_FILE, consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
    
  • 验证客户端请求格式:确保客户端发送请求时,顶层Content-Type为multipart/form-data,且文件参数名与@RequestPart("file")中的file完全一致,避免直接发送image/jpeg类型的原始请求(这不属于multipart上传范畴)。

3. Spring WebFlux配置multipart文件上传的常见陷阱

  • 混淆Servlet与WebFlux栈配置:很多开发者会照搬Spring MVC的spring.servlet.multipart配置,但WebFlux不识别该节点,必须使用spring.webflux.multipart。
  • consumes参数误用:不要在文件上传接口添加MediaType.ALL_VALUE,这会破坏Spring对multipart请求的解析逻辑,只需指定multipart/form-data即可。
  • 内存大小限制遗漏:spring.codec.max-in-memory-size设置过小会导致大文件解析失败,需根据业务需求调整,超出该阈值的文件会自动写入临时文件(需确保临时目录有足够存储空间)。
  • 协程方法的阻塞风险:如果S3Service.upload是阻塞式方法,需用withContext(Dispatchers.IO)包裹,避免阻塞WebFlux的事件循环线程。
  • 请求参数名不匹配:@RequestPart的参数名必须与客户端传入的文件参数名完全一致,否则会出现找不到文件part的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 07:05:23