element ui upload组件的多附件上传是循环调用上传接口的,在每次on-change 改变后调用后端接口交互
这样的话就会导致后台接口容易出错
想要点一下就可以上传多个附件的问题(最后也是实现了,但是问题比较多)
1.需要指定请求内容类型和token
不指定请求类型的话好像会默认转换为这个最好加上
const config = { headers: { 'Content-Type': 'multipart/form-data',
"Authorization": "Bearer " + getToken()}}
2.java程序接收使用(这俩种都可以)
@RequestParam("file") MultipartFile[] file
@RequestParam("file") List<MultipartFile> file
3.需要添加
:on-change="handleChangeFile"
handleChangeFile(file, fileList) {
this.upload.fileList = fileList.slice(-4);
//这个-4取决于最大附件上传个数
//因为是默认从后往前取数据
/*fileList.slice(-4):介绍
1. 方法介绍 : blob.slice(); 属于Blob对象的一个方法,而File对象是继承Blob对象的,因此File对象也含有slice方法
2. 参数介绍 : blob.slice(startByte,endByte); 这里需要注意它的参数,第一个参数startByte表示文件起始读取Byte字节,第二个参数则是结束读取字节。这里重点注意一下第二个参数,一开始我以为它是读取的长度,因为是在阅读《javascript高级程序设计》时它的例子介绍用length作为形参。结果我在进行文件分割上传的时候,一直获取不到第二次请求后的数据。
3.返回值 : newBlob = blob.slice(startByte,endByte); 它返回的仍然是一个Blob类型*/
},
(如果不添加会出现报错)提示成功但是没数据
参数也没有附件
java后台报错:Required request part 'file' is not present
(出现这个报错,一定要查看是不是上传的文件为空)
4.完整案例
vue前台
<template>
<div class="dashboard-editor-container">
<el-upload
ref="upload"
:limit="upload.fileLimit"
class="upload-demo"
accept=""
multiple
:action="upload.url"
:headers="upload.headers"
:before-upload="beforeUpload"
:file-list="fileList"
:on-exceed="handleExceed"
:on-change="handleChangeFile"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" size="small" type="success" :loading="upload.isUploading" @click="submitUpload">上传到服务器</el-button>
</el-upload>
</div>
</template>
<script>
import {getToken} from '@/utils/auth';
import axios from 'axios'
export default {
name: 'Index',
components: {
},
data() {
return {
upload: {
// 是否禁用上传
isUploading: false,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/common1/uploadFile",//单附件上传
fileList: [],
// 允许的文件类型
fileType: [ "pdf", "doc", "docx", "xls", "xlsx","txt","png","jpg", "bmp", "jpeg"],
fileLimit:4
},
}
},
methods: {
handleChangeFile(file, fileList) {
this.upload.fileList = fileList.slice(-4);//-4为附件最大上传数
},
//上传文件之前
beforeUpload(file){
if (file.type != "" || file.type != null || file.type != undefined){
//截取文件的后缀,判断文件类型
const FileExt = file.name.replace(/.+\./, "").toLowerCase();
//计算文件的大小
const isLt100M = file.size / 1024 / 1024 < 100; //这里做文件大小限制
//如果大于100M
if (!isLt100M) {
this.$modal.msgError("上传文件大小不能超过 50MB!");
return false;
}
//如果文件类型不在允许上传的范围内
if(this.upload.fileType.includes(FileExt)){
return true;
}
else {
this.$modal.msgError("上传文件格式不正确!");
return false;
}
}
},
//超出文件个数的回调
handleExceed(){
this.$modal.msgError("超出最大上传文件数量的限制!");
},
// 文件提交处理
async submitUpload() {
/*多附件上传*/
let formData = new FormData();
this.upload.fileList.forEach((item) => {
formData.append("file", item.raw);
});
const config = { headers: {'Content-Type': 'multipart/form-data',
"Authorization": "Bearer " + getToken()}}
await axios.post(process.env.VUE_APP_BASE_API+"/common1/uploadFiles",formData,config).then((res)=>{
//成功处理
this.$message.success("附件上传成功!");
})
},
}
}
</script>
java后台代码:
@RestController
@RequestMapping("/common1")
public class FileController{
/**
* 通用上传请求(多个)
*/
@PostMapping("/uploadFiles")
public AjaxResult uploadFiles(@RequestParam("file") MultipartFile[] file) throws Exception
{
if(file!=null && file.length>0){
throw new Exception("获取到的文件个数!"+file.length);
}
}
}