Spring Boot PUT接口报错:不支持application/octet-stream媒体类型
解决Spring Boot接口接收JSON+文件时的HttpMediaTypeNotSupportedException问题
错误原因分析
报错Content-Type 'application/octet-stream' is not supported,本质是前端通过FormData传递的请求部分(part)未设置正确媒体类型,导致Spring无法解析为对应参数类型:
- 传递
profile_detailsJSON时,未指定Content-Type: application/json,FormData默认将字符串参数标记为text/plain或application/octet-stream,Spring无法自动绑定到UpdateProfileDetailsRequest对象。 - 直接传递base64格式的图片字符串而非Blob/File对象,导致该部分Content-Type不符合MultipartFile的解析要求。
具体解决方案
1. 修正前端FormData构造逻辑
在React中构造FormData时,必须为每个part指定正确的Content-Type:
- 处理JSON参数:将JSON对象转为字符串后,显式指定
application/json类型 - 处理base64图片:将base64字符串转为Blob对象,再添加到FormData,并指定图片对应的媒体类型(如
image/png、image/jpeg)
示例React代码:
// 构造profile_details数据 const profileData = { email_id: "xxxxxxx@icloud.com" }; const formData = new FormData(); // 添加JSON参数,指定Content-Type formData.append( 'profile_details', JSON.stringify(profileData), { contentType: 'application/json' } ); // base64转Blob并添加图片 const base64Image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."; // 你的base64数据 const imageBlob = base64ToBlob(base64Image); formData.append('profile_image', imageBlob, 'profile.png'); // 第三个参数为文件名 // base64转Blob工具函数 function base64ToBlob(base64) { const parts = base64.split(';base64,'); const contentType = parts[0].split(':')[1]; const raw = window.atob(parts[1]); const uInt8Array = new Uint8Array(raw.length); for (let i = 0; i < raw.length; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], { type: contentType }); } // 发送PUT请求 fetch(`/api/profiles/${profileId}`, { method: 'PUT', body: formData }) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err));
2. 后端接口优化(可选但推荐)
在后端接口中显式指定每个@RequestPart的预期媒体类型,避免解析歧义:
@PutMapping(value = "/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity<ProfileDetails> updateProfileDetails( @RequestPart(value = "profile_details", contentType = MediaType.APPLICATION_JSON_VALUE) UpdateProfileDetailsRequest updateProfileDetailsRequest, @RequestPart("profile_image") MultipartFile profileImage, @PathVariable("id") String profileId) { // 修正笔误:使用传入的请求对象而非新创建的空对象 var updatedProfile = service.updateProfileDetails(updateProfileDetailsRequest, profileId); return ResponseEntity.ok(updatedProfile); }
3. 调试验证步骤
- 使用Postman手动构造请求:创建multipart/form-data请求,分别添加
profile_details(选raw-JSON类型,Content-Type设为application/json)和profile_image(选file类型),测试接口是否正常响应。 - 查看浏览器Network面板:检查请求中每个form data part的Content-Type是否符合预期,确认无
application/octet-stream的异常项。
内容的提问来源于stack exchange,提问作者Ryuzaki L
相关产品推荐
相关产品推荐

