前后端系统图片处理
2025-02-18 17:55:33

项目需求要保存图书封面到系统中。我们把这个问题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){
    // 上传图片,把图片保存到cover成员中
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来访问图片即可。