SpringBoot如何将图片与请求体存入数据库?求助解决序列化错误
错误信息
已解析异常:org.springframework.http.converter.HttpMessageNotReadableException: JSON解析错误:无法将字符串"\fakepath\book.jpg"反序列化为
byte[]类型:无法将VALUE_STRING解码为base64(MIME-NO-LINEFEEDS):base64内容中存在非法字符':'(代码0x3a);嵌套异常为com.fasterxml.jackson.databind.exc.InvalidFormatException:无法将字符串"\fakepath\book.jpg"反序列化为byte[]类型:无法将VALUE_STRING解码为base64(MIME-NO-LINEFEEDS):base64内容中存在非法字符':'(代码0x3a),位置:[来源:(org.springframework.util.StreamUtils$NonClosingInputStream);行:1,列:162](引用链:com.msys.smartkart.entity.Product["image"])
问题原因
前端提交请求时,错误地将图片路径字符串(如"\fakepath\book.jpg")填入了Product的image字段,后端Jackson尝试把这个字符串解码成byte[]时失败——路径中的':'不属于base64合法字符,导致反序列化报错。
解决方案
1. 实体类添加注解忽略image字段的JSON处理
给Product的image字段加上@JsonIgnore,避免Jackson自动尝试解析或序列化这个byte[]字段:
package com.msys.smartkart.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; import com.fasterxml.jackson.annotation.JsonIgnore; import javax.persistence.*; import java.util.Date; @Entity @Data @AllArgsConstructor @NoArgsConstructor public class Product { @Id Integer id; String productName; String color; String description; String details; Integer price; @Lob @JsonIgnore // 跳过JSON序列化/反序列化,避免Jackson处理byte[] byte[] image; @CreationTimestamp Date date; }
2. 调整控制器接口参数接收方式
控制器需要用@RequestPart分别接收Product实体和MultipartFile图片,确保图片通过文件流传递,而非字符串路径:
@PostMapping("/products") public ResponseEntity<String> addProduct( @RequestPart("product") Product product, @RequestPart("image") MultipartFile multipartFile) throws IOException { productService.addProduct(product, multipartFile); return ResponseEntity.ok("产品添加成功"); }
3. 简化业务方法
无需新建Product对象,直接给传入的Product设置图片字节数组即可:
@Override public void addProduct(Product product, MultipartFile multipartFile) throws IOException { log.info("产品详情: {}", product); byte[] imageBytes = multipartFile.getBytes(); log.info("图片字节数组长度: {}", imageBytes.length); product.setImage(imageBytes); productRepository.save(product); log.info("产品及图片已保存"); }
4. 前端提交方式
前端需要使用FormData组合JSON格式的Product和文件,示例代码:
const formData = new FormData(); // 构造Product对象 const product = { id: 1, productName: "示例书籍", price: 60, color: "蓝色", description: "入门编程书籍", details: "含100个实战案例" }; // 添加JSON字符串形式的product formData.append("product", JSON.stringify(product)); // 添加选择的图片文件 formData.append("image", document.getElementById("imageInput").files[0]); // 发送请求 fetch("/products", { method: "POST", body: formData }).then(res => res.text()) .then(msg => console.log(msg)) .catch(err => console.error(err));
内容的提问来源于stack exchange,提问作者shiva shanker

