Apache HttpClient发送Multipart请求,API未识别picture文件的问题咨询
Multipart请求中Spring无法接收MultipartFile参数的问题解决
问题描述
我有一个用于测试API和数据库的虚拟用户生成程序,因包含以bytearray表示的“文件”,故通过Multipart请求发送数据。使用Apache HttpClient构建并执行请求的Kotlin代码如下:
val req = HttpPost("http://localhost:8080/api/createuser") req.entity = MultipartEntityBuilder .create() .addTextBody("key", key) .addTextBody("username", user.username) .addTextBody("password", "1234") .addTextBody("data", user.encode()) .addBinaryBody("picture", ByteArray(10) { 0 }) .build() client.execute(req) { println(if(it.code == 200) "success" else "failure") }
然而,API端点提示找不到必填的picture部分。API已启用Multipart功能,其他所有参数均能正常接收。以下是该端点的RequestMapping代码:
fun createUser( @RequestPart key: String, @RequestPart username: String, @RequestPart password: String, @RequestPart data: String, @RequestPart picture: MultipartFile ) { require(key == masterKey) println("File: ${picture.bytes}") val u = User() with(u) { this.username = username this.password = password this.userData = data } userRepository.save(u) }
已确认请求格式合法,且已将max-file-size和max-request-size配置项调至15MB(远大于测试用的10字节),为何仅picture文件未被API接收?
解决方案
问题出在addBinaryBody的调用方式上——当只传入字节数组时,Apache HttpClient不会自动设置文件名和Content-Type,而Spring的@RequestPart绑定MultipartFile时,默认需要请求部分包含符合文件上传规范的元数据(比如文件名)。
修改请求构建代码,为picture部分指定文件名和Content-Type即可:
val req = HttpPost("http://localhost:8080/api/createuser") req.entity = MultipartEntityBuilder .create() .addTextBody("key", key) .addTextBody("username", user.username) .addTextBody("password", "1234") .addTextBody("data", user.encode()) // 新增文件名和Content-Type参数 .addBinaryBody("picture", ByteArray(10) { 0 }, ContentType.DEFAULT_BINARY, "dummy.jpg") .build() client.execute(req) { println(if(it.code == 200) "success" else "failure") }
关键原因说明
- Spring的
MultipartFile要求请求中的对应part必须是标准的文件类型multipart部分,即Content-Disposition头必须包含filename参数。 - 仅传入字节数组时,HttpClient生成的part只有
name="picture"属性,缺少filename,Spring无法将其识别为MultipartFile类型。 - 指定文件名后,HttpClient会自动生成符合规范的
Content-Disposition头(格式类似form-data; name="picture"; filename="dummy.jpg"),Spring就能正确绑定到MultipartFile参数上。
内容的提问来源于stack exchange,提问作者GPorubanTKK
相关产品推荐
相关产品推荐

