如何实现Spring Controller向MySQL数据库传输Blob数据
实现通过API将图片存入数据库的完整方案
现有代码情况
1. Post实体类
@Entity(name = "posts") public class Post { @Id @Column(name = "Id", nullable = false) private String id; @Column(name = "Post_title", nullable = false) private String title; @Column(name = "creator", nullable = false) private String creator; @Lob @Column(name = "post_image", nullable = false) private Byte[] postImage; @Column(name = "descriptions", nullable = false) private String descriptions; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCreator() { return creator; } public void setCreator(String creator) { this.creator = creator; } public Byte[] getPostImage() { return postImage; } public void setPostImage(Byte[] postImage) { this.postImage = postImage; } public String getDescriptions() { return descriptions; } public void setDescriptions(String descriptions) { this.descriptions = descriptions; } }
2. Spring控制器代码
@RestController @RequestMapping("/api/posts") public class PostController { @Autowired private PostRepository postRepository; @PostMapping public ResponseEntity<Post> createPost(@RequestBody Post post) { Post newPost = postRepository.save(post); return new ResponseEntity<>(newPost, HttpStatus.CREATED); } }
3. 前端图片转字节逻辑
const inputElement = document.getElementById("image-input"); inputElement.addEventListener("change", function() { const file = inputElement.files[0]; const reader = new FileReader(); reader.readAsBinaryString(file); reader.onload = function() { const blob = new Blob([reader.result], { type: file.type }); const byteArray = new Uint8Array(blob); // Now you can send the byteArray to your API endpoint }; });
完整实现步骤
一、前端代码修改:改用Base64格式传输图片
直接传递Uint8Array在JSON序列化后会丢失类型信息,后端无法直接映射到Byte[]。推荐将图片转为Base64字符串,更适配JSON传输:
const inputElement = document.getElementById("image-input"); const titleInput = document.getElementById("title-input"); const creatorInput = document.getElementById("creator-input"); const descInput = document.getElementById("desc-input"); const submitBtn = document.getElementById("submit-btn"); let base64Image = ""; inputElement.addEventListener("change", function() { const file = inputElement.files[0]; const reader = new FileReader(); // 直接读取为DataURL格式(包含Base64编码) reader.readAsDataURL(file); reader.onload = function() { // 去除前缀,仅保留纯Base64编码部分 base64Image = reader.result.split(",")[1]; }; }); submitBtn.addEventListener("click", async function() { const postData = { id: self.crypto.randomUUID(), // 前端生成唯一ID,也可由后端生成 title: titleInput.value, creator: creatorInput.value, descriptions: descInput.value, postImage: base64Image }; try { const response = await fetch("/api/posts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(postData) }); if (response.ok) { const savedPost = await response.json(); console.log("帖子创建成功", savedPost); // 这里可添加表单重置、页面跳转等后续逻辑 } else { console.error("创建失败"); } } catch (error) { console.error("请求出错", error); } });
二、后端代码调整:处理Base64到Byte[]的转换
前端传的Base64字符串需要转为实体类要求的Byte[]类型,修改控制器方法如下:
import java.util.Base64; import java.util.Map; import java.util.UUID; @RestController @RequestMapping("/api/posts") // 跨域需求添加此注解:@CrossOrigin(origins = "你的前端域名") public class PostController { @Autowired private PostRepository postRepository; @PostMapping public ResponseEntity<Post> createPost(@RequestBody Map<String, Object> requestMap) { Post post = new Post(); // 可选:由后端生成ID,替代前端生成 post.setId(UUID.randomUUID().toString()); post.setTitle((String) requestMap.get("title")); post.setCreator((String) requestMap.get("creator")); post.setDescriptions((String) requestMap.get("descriptions")); // 解析Base64字符串为byte[],再转为Byte[]包装类型 String base64Image = (String) requestMap.get("postImage"); byte[] rawBytes = Base64.getDecoder().decode(base64Image); Byte[] wrappedBytes = new Byte[rawBytes.length]; for (int i = 0; i < rawBytes.length; i++) { wrappedBytes[i] = rawBytes[i]; } post.setPostImage(wrappedBytes); Post newPost = postRepository.save(post); return new ResponseEntity<>(newPost, HttpStatus.CREATED); } }
三、关键注意事项
- 数据库字段:
post_image因使用@Lob注解,会自动映射为数据库的大字段类型(如MySQL的LONGBLOB),确保字段长度足够容纳图片内容。 - 表单验证:前端需添加非空校验,避免空字段导致后端报错。
- 跨域配置:若前后端不在同一域名,需在Spring控制器添加
@CrossOrigin注解,或全局配置跨域规则。
内容的提问来源于stack exchange,提问作者Simeon Tuyoleni
相关产品推荐
相关产品推荐

