一.背景
文件上传项目可参考:点击预览
1.最简单也是最普遍的做法是form表单提交,其实前端提交到后端也是难以离开form表单提交,
一般有两种方式来处理文件、图片上传:
- 先上传,获取返回路径,再整个表单提交后端保存;
- 普通数据与文件图片同时提交后端,由后端处理
优点比较
- 第一种可以优先处理文件上传,异步处理,节省用户提交loading的时间,特别是一些大文件
- 第二种在最后提交才进行文件处理,没有脏数据,节省了文件服务器空间和流量
缺点比较,可以说刚好相反,第一种只有一选择文件,马上就上传,用户可以在最后提交之前一直change文件,就可能不断上传了一些没必要的文件图片,造成了各种文件脏数据,除非通过某些逻辑去删除这些脏文件(定时刷数据或提交的时候判断用户最终保存的数据来删除脏数据)
这里作者采取第二种方式,相对于第一种,实现难度稍微大些
二.前端html实现
element上传官方文档
on-success、on-error其实就是上面说的第一种方式才会用到的,作者感觉element就是推荐用异步的方式来实现的,通过action提交到指定上传接口
前端实现源码
<el-form-itemlabel="图片":required="form.postsType !== '2'"><el-uploadaction=""list-type="picture-card":auto-upload="false":limit="9":before-upload="beforeUpload":on-change="handleChange":on-preview="handlePictureCardPreview":disabled="disabled":on-remove="handleRemove"><iclass="el-icon-plus"></i></el-upload><divstyle="font-size: 12px;color: #666;">
只能上传jpg/png文件,且不超过 2MB,最多上传 9 张图片
</div><el-dialog:visible.sync="dialogVisible"><imgwidth="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 =newFormData();for(const file ofthis.form.files){//多个文件全部都放到filesif(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")})publicResult<Posts>add(@RequestParam("title")String title,@RequestParam(value ="files",required =false)MultipartFile[] files
){PostsReq postsReq =newPostsReq();
postsReq.setTitle(title);
postsReq.setFiles(files);return postsService.add(JwtUtil.getUserId(),postsReq);}
源码解析:
作者一开始是想着用@RequestBody注解来接收整个数据对象的,但是这样的话会报错,具体错误信息作者没有记录下来,大概的意思就是MultipartFile类型不支持,没有构造方法那一类的,然后看了一下MultipartFile的源码
居然是interface的~,原来如此(理所当然认为应该是class的,哈哈哈,难怪),有更加深入研究的同学麻烦留言也分享一下,感谢!
java文件上传处理实现:
publicStringuploadImage(MultipartFile file){if(file ==null)thrownewBizException("图片不能为空");//得到上传文件的文件名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)thrownewBizException("图片大小不能大于2M");if(!isImage(suffixName))thrownewBizException("不是图片格式");// 这里可以用uuid等 拼接新图片名String newFileName =UUID.randomUUID().toString().replace("-","")+ suffixName;// 创建路径String destFileName = fileUploadConfig.getImageRealPath()+File.separator + newFileName;File destFile =newFile(destFileName);if(!destFile.getParentFile().exists())
destFile.getParentFile().mkdirs();try{//将图片保存到文件夹里
file.transferTo(newFile(destFileName));}catch(IOException e){
e.printStackTrace();thrownewBizException("图片上传错误");}//返回相对路径存储return fileUploadConfig.getImageMapperPath()+ newFileName;}/**
* 传进 .jpg 类似的格式 判断是否时图片格式
* @param suffixName 图片格式后缀
* @return
*/publicstaticbooleanisImage(String suffixName){List<String> strings =Arrays.asList(".webp",".png",".jpg",".jif",".jpeg");return strings.contains(suffixName);}
有更加好的实现方式的,欢迎留言,大家分享,共同学习、共同进步~
版权归原作者 愛芳芳 所有, 如有侵权,请联系我们删除。