使用@RequestBody发送MULTIPART_FORM_DATA POST请求遇406错误的解决
解决Multipart POST请求的406 Not Acceptable错误
我来帮你拆解下问题根源,再一步步解决这个406错误:
问题出在哪?
@RequestBody不适合处理Multipart请求:@RequestBody是用来接收JSON/XML这类单一格式的请求体的,但你要发送的是包含文件的multipart/form-data表单请求,两者不兼容。produces属性用错了:这个属性是告诉客户端「接口返回什么类型的数据」,而你需要的是指定接口能接收什么类型的请求,应该用consumes。- Blob类型无法直接绑定:实体类里的
Blob字段没法直接从Multipart文件自动转换,需要手动处理文件到Blob的转换逻辑。
解决方案步骤
1. 修正控制器方法
把@RequestBody换成@RequestPart,同时调整请求接收类型,处理文件和表单数据:
@RequestMapping(value = "aboutMe", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public String saveAboutMe(@RequestPart("author") Author author, @RequestPart("image") MultipartFile image) throws SQLException { // 处理图片文件转Blob if (image != null && !image.isEmpty()) { Blob blob = new SerialBlob(image.getBytes()); author.setImage(blob); } // 顺便设置修改时间(如果业务需要的话) author.setModifiedTime(new Date()); authorService.saveAboutMe(author); return "saved"; }
@RequestPart可以分别接收Multipart请求里的不同部分:一个是JSON格式的author数据,一个是图片文件。consumes = MediaType.MULTIPART_FORM_DATA_VALUE才是正确的配置,用来声明接口接收Multipart类型的请求。
2. 实体类优化(可选)
如果觉得Blob处理起来麻烦,可以把实体类里的Blob换成byte[],这样文件转换更简单:
@Entity @Table(name = "author") public class Author { // 其他字段保持不变 @Column(name = "image") @Lob private byte[] image; // 替换原有的Blob类型 // 对应的getter和setter方法 }
此时控制器里的图片转换代码可以简化为:
author.setImage(image.getBytes());
3. 正确发送请求的姿势
用Postman或其他工具测试时,要按Multipart请求的规则构造:
- 请求方法选POST,地址填你的接口URL
- Body选择
form-data格式 - 添加两个参数:
- 第一个参数名
author,类型选raw,格式选JSON,输入Author的JSON数据(比如{"id":1,"title":"我的简介","aboutMe":"这是关于我的内容"}) - 第二个参数名
image,类型选File,选择本地的图片文件
- 第一个参数名
为啥会出现406错误?
406的本质是:服务器无法返回客户端请求的Accept类型内容。你之前设置了produces = MediaType.MULTIPART_FORM_DATA_VALUE,相当于告诉客户端「我返回的是Multipart格式数据」,但你的方法返回的是普通字符串"saved"(属于text/plain类型),服务器没法生成符合要求的Multipart响应,所以直接返回了406错误。把produces换成consumes,再修正请求体的接收方式,问题就解决了。
内容的提问来源于stack exchange,提问作者Gulshan
相关产品推荐
相关产品推荐

