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
相关产品推荐
相关产品推荐

