一.背景
文件上传项目可参考:点击预览
1.最简单也是最普遍的做法是form表单提交,其实前端提交到后端也是难以离开form表单提交,
一般有两种方式来处理文件、图片上传:
- 先上传,获取返回路径,再整个表单提交后端保存;
- 普通数据与文件图片同时提交后端,由后端处理
优点比较
- 第一种可以优先处理文件上传,异步处理,节省用户提交loading的时间,特别是一些大文件
- 第二种在最后提交才进行文件处理,没有脏数据,节省了文件服务器空间和流量
缺点比较,可以说刚好相反,第一种只有一选择文件,马上就上传,用户可以在最后提交之前一直change文件,就可能不断上传了一些没必要的文件图片,造成了各种文件脏数据,除非通过某些逻辑去删除这些脏文件(定时刷数据或提交的时候判断用户最终保存的数据来删除脏数据)
这里作者采取第二种方式,相对于第一种,实现难度稍微大些
二.前端html实现
element上传官方文档
on-success、on-error其实就是上面说的第一种方式才会用到的,作者感觉element就是推荐用异步的方式来实现的,通过action提交到指定上传接口
前端实现源码
<el-form-item label="图片" :required="form.postsType !== '2'">
<el-upload
action=""
list-type="picture-card"
:auto-upload="false"
:limit="9"
:before-upload="beforeUpload"
:on-change="handleChange"
:on-preview="handlePictureCardPreview"
:disabled="disabled"
:on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
<div style="font-size: 12px;color: #666;">
只能上传jpg/png文件,且不超过 2MB,最多上传 9 张图片
</div>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</el-form-item>
同时定义属性
dialogImageUrl: '',//窗口预览图片路径
dialogVisible: false,//预览窗口是否打开
disabled: false,//是否禁用上传操作
源码解析:
- :limit=“9” //最多可上传9张图片
- :before-upload=“beforeUpload”//上传之前,即选择图片后调用方法
- :on-change=“handleChange”//选择图片上传调用方法
- :on-preview=“handlePictureCardPreview”//预览图片调用方法
- :disabled=“disabled”//是否禁用上传操作
- :on-remove=“handleRemove”//上传已选择的图片
三.js方法实现
js源码
beforeUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!')
}
return isLt2M
},
handleRemove(file, fileList) {
this.form.files = fileList;
console.info(this.form);
},
handleChange(file, fileList){
this.form.files = fileList;
console.info(this.form);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
源码解析:
方法意义上面已经说过了,其中this.form.files定义为一个数组,暂存上传的文件
form: {
files: [],
title: ''
},
组装数据请求上传到后端:
let formData = new FormData();
for (const file of this.form.files) {//多个文件全部都放到files
if(file.raw) {
formData.append('files', file.raw);
}
}
formData.append('title',this.form.title);
add(formData).then(res => {
this.loading = false;
if(res.code === 200){
this.$message.success(res.msg);
}
},error => {
this.loading = false;
})
四.java后端处理
controller:
@PostMapping("/add")
@ApiOperation(value = "添加", notes = "添加")
@ApiImplicitParams({
@ApiImplicitParam(name = "title", value = "标题", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "files", value = "上传图片列表", required = false, dataType = "MultipartFile[]", paramType = "query")
})
public Result<Posts> add(
@RequestParam("title") String title,
@RequestParam(value = "files",required = false) MultipartFile[] files
) {
PostsReq postsReq = new PostsReq();
postsReq.setTitle(title);
postsReq.setFiles(files);
return postsService.add(JwtUtil.getUserId(),postsReq);
}
源码解析:
作者一开始是想着用@RequestBody注解来接收整个数据对象的,但是这样的话会报错,具体错误信息作者没有记录下来,大概的意思就是MultipartFile类型不支持,没有构造方法那一类的,然后看了一下MultipartFile的源码
居然是interface的~,原来如此(理所当然认为应该是class的,哈哈哈,难怪),有更加深入研究的同学麻烦留言也分享一下,感谢!
java文件上传处理实现:文章来源:https://www.toymoban.com/news/detail-771757.html
public String uploadImage(MultipartFile file) {
if (file == null)
throw new BizException("图片不能为空");
//得到上传文件的文件名
String fileName = file.getOriginalFilename();
//以传入的字符串开头,到该字符串的结尾,前开后闭
String suffixName = fileName.substring(fileName.lastIndexOf("."));
long size = file.getSize();
double mul = NumberUtil.div(size, (1024 * 1024), 2);
// 自定义异常
if (mul > 2)
throw new BizException("图片大小不能大于2M");
if (!isImage(suffixName))
throw new BizException("不是图片格式");
// 这里可以用uuid等 拼接新图片名
String newFileName = UUID.randomUUID().toString().replace("-", "") + suffixName;
// 创建路径
String destFileName = fileUploadConfig.getImageRealPath() + File.separator + newFileName;
File destFile = new File(destFileName);
if (!destFile.getParentFile().exists())
destFile.getParentFile().mkdirs();
try {
//将图片保存到文件夹里
file.transferTo(new File(destFileName));
} catch (IOException e) {
e.printStackTrace();
throw new BizException("图片上传错误");
}
//返回相对路径存储
return fileUploadConfig.getImageMapperPath() + newFileName;
}
/**
* 传进 .jpg 类似的格式 判断是否时图片格式
* @param suffixName 图片格式后缀
* @return
*/
public static boolean isImage(String suffixName) {
List<String> strings = Arrays.asList(".webp", ".png", ".jpg", ".jif", ".jpeg");
return strings.contains(suffixName);
}
有更加好的实现方式的,欢迎留言,大家分享,共同学习、共同进步~文章来源地址https://www.toymoban.com/news/detail-771757.html
到了这里,关于java MultipartFile+vue+element 批量上传文件、图片,与普通数据同时提交保存才上传到后端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!