使用SpringBoot+Vue+Antd 编写上传文件功能
前端:使用Vue组件库
<template>
<div class="clearfix">
<a-upload :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove">
<a-button>
<upload-outlined></upload-outlined>
Select File
</a-button>
</a-upload>
<a-button
type="primary"
:disabled="fileList.length === 0"
:loading="uploading"
style="margin-top: 16px"
@click="handleUpload"
>
{{ uploading ? 'Uploading' : 'Start Upload' }}
</a-button>
</div>
</template>
<script lang="ts">
import request from 'umi-request';
import { UploadOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { defineComponent, ref } from 'vue';
import type { UploadProps } from 'ant-design-vue';
export default defineComponent({
components: {
UploadOutlined,
},
setup() {
const fileList = ref<UploadProps['fileList']>([]);
const uploading = ref<boolean>(false);
const handleRemove: UploadProps['onRemove'] = file => {
const index = fileList.value.indexOf(file);
const newFileList = fileList.value.slice();
newFileList.splice(index, 1);
fileList.value = newFileList;
};
const beforeUpload: UploadProps['beforeUpload'] = file => {
fileList.value = [...fileList.value, file];
return false;
};
const handleUpload = () => {
const formData = new FormData();
fileList.value.forEach((file: UploadProps['fileList'][number]) => {
//这个位置是个坑,这里写的是files[] 参数名,一般我们在后端习惯接受的file名称
//所以这里在配合后端发送请求的时候,会找不到file参数名称
formData.append('files[]', file as any);
});
uploading.value = true;
// You can use any AJAX library you like
request('https://www.mocky.io/v2/5cc8019d300000980a055e76', {
method: 'post',
data: formData,
})
.then(() => {
fileList.value = [];
uploading.value = false;
message.success('upload successfully.');
})
.catch(() => {
uploading.value = false;
message.error('upload failed.');
});
};
return {
fileList,
uploading,
handleRemove,
beforeUpload,
handleUpload,
};
},
});
</script>
后端:使用SpringBoot
Controller层使用file接收
所以前端请求的时候也要用file
public ResponseEntity<ModelTrainingAnnexDTO> createModelTrain(@RequestParam("qdtzCode") String qdtzCode, @RequestParam("file") MultipartFile file) throws IOException {
InputStream inputStream = file.getInputStream();
ModelTrainingAnnex modelTrainingAnnex = StorageUtil.touch(inputStream, qdtzCode, file.getOriginalFilename(), false);
return null;
}
public static ModelTrainingAnnex touch(InputStream source, String qdtzCode, String targetPath, Boolean ignoreSuffix) {
// 文件流是否存在
if (source == null) {
log.error("文件流为 null !");
throw new RuntimeException("文件流为 null !");
}
// 处理文件路径
targetPath = targetPathHandle(targetPath);
if (targetPath == null) {
log.error("未拼接文件名");
throw new RuntimeException("未拼接文件名");
}
// 文件名
String name = FileNameUtil.getName(targetPath);
String suffix = FileNameUtil.getSuffix(targetPath);
if (!name.contains(".") && !ignoreSuffix) {
log.error("文件无后缀名");
throw new RuntimeException("文件无后缀名");
}
// 保存文件的绝对路径
String path = StrUtil.format("{}{}{}.{}", GLOBAL_ROOT_PATH, qdtzCode + "\\", targetPath.replace(name, String.valueOf(IdUtil.getSnowflakeNextId())), suffix);
// 保存文件
OutputStream target = FileUtil.getOutputStream(FileUtil.touch(path));
Long fileSize = 0L;
try {
fileSize = NioUtil.copyByNIO(source, target, NioUtil.DEFAULT_MIDDLE_BUFFER_SIZE, null) / 1024;
} catch (Exception e) {
log.error("保存文件异常:", e);
} finally {
IoUtil.close(target);
}
// 最大排序号
ModelTrainingAnnex maxSeq = modelTrainingAnnexRepository.findTopByOrderBySequenceDesc();
// 当前登录用户
Optional<String> userName = SecurityUtils.getCurrentUserName();
// 保存到数据库
ModelTrainingAnnex ModelTrainingAnnex = null;
try {
ModelTrainingAnnex = new ModelTrainingAnnex();
ModelTrainingAnnex.setId(IdUtil.simpleUUID().toUpperCase(Locale.ROOT));
ModelTrainingAnnex.setName(name);
ModelTrainingAnnex.setFileType(suffix);
ModelTrainingAnnex.setFilePath(path);
ModelTrainingAnnex.setFileSize(fileSize);
ModelTrainingAnnex.setIsInternetUrl(false);
ModelTrainingAnnex.setInternetiUrlPrefix(null);
ModelTrainingAnnex.setUploadTime(DateUtil.toInstant(new Date()));
ModelTrainingAnnex.setCreator(userName.orElse(null));
ModelTrainingAnnex.setCreatedTime(DateUtil.toInstant(new Date()));
ModelTrainingAnnex.setModifiedTime(DateUtil.toInstant(new Date()));
ModelTrainingAnnex.setSequence(maxSeq == null ? 0 : maxSeq.getSequence() + 1);
ModelTrainingAnnex.setQdtzCode(qdtzCode);
if (suffix.equals("jsonl")) {
ModelTrainingAnnex.setModelState("0");
} else if (suffix.equals("xls") || suffix.equals("xlsx")) {
ModelTrainingAnnex.setModelState("3");
}
modelTrainingAnnexRepository.save(ModelTrainingAnnex);
} catch (Exception e) {
ModelTrainingAnnex = null;
// 删除文件
rm(path);
log.error("保存到数据库异常,删除文件", e);
}
return ModelTrainingAnnex;
}