项目需求要保存图书封面到系统中。我们把这个问题Divide and Conquer。
首先是图片如何在后端存储?一个朴素的想法是直接把上传的图片以二进制的形式直接保存到MySql数据库中。但是这样做的话数据库的体积会大幅增大,可能会影响数据库性能,而且图片的管理不够灵活。因此一个更优解是只在数据库中存储图片文件在本地的路径,然后把上传的图片存储在本地的文件管理系统中。这样不仅数据库轻量化易于维护,而且图片管理灵活,可以自由切换位置,实现了解耦。
接着是后端如何接收图片?以Spring Boot为例,我们在Controller中撰写以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @PostMapping("upload") public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file, String id) { if (file.isEmpty()) { return ResponseEntity.ok("上传失败,请选择文件"); } String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename(); String filePath = localPath + fileName; try { file.transferTo(new java.io.File(filePath)); } catch (Exception e) { e.printStackTrace(); return ResponseEntity.ok("上传失败"); } Book book = bookService.getById(id); book.setImageUrl("http://localhost:8082/images/" + fileName); bookService.updateById(book); return ResponseEntity.ok("上传成功"); }
|
然后是前端上传图片。在Vue前端需要一个el-upload
组件。其中http-request会屏蔽掉action,可以实现点击确认后和图书属性一起上传。
1 2 3 4 5
| <el-upload v-else-if="item.prop === 'imageUrl'" :http-request="upload" action="#" drag accept="image/*" :auto-upload="true" :limit="1"> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| upload (options){ const formdata = new FormData() formdata.append('file', options.file) this.cover = formdata }
doSubmit () { this.BookService.upload(this.cover, this.inputForm.id).then(({ data }) => { this.inputForm.imageUrl = data this.$message.success('上传成功') }) },
export default class BookService { upload (formData, id) { return request({ url: '/books/upload', method: 'post', data: formData, params: {id: id} }) } }
|
最后是前端显示保存的图片。由于浏览器后端不能直接从文件系统访问图片,我们需要使用Springboot后端静态代理图片。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.example.demo.config;
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/images/**") .addResourceLocations("file:D:/images/"); } }
|
这样只需要在前端使用img
指定src
来访问图片即可。