前言

碰到这样一个需求:

       前端在新增数据的时候将表单中的多个文件和表单的其余参数一并传递给后端的某个接口。

代码实现

1.前端

代码如下:

<el-upload
:before-upload="beforeUpload"
:limit="1"
accept="image/jpeg,image/gif,image/png"
class="flex"
:file-list="fileList2"
:auto-upload="false"

action="#"
ref='namePlatePhoto'
>
<el-button size="small">
上传文件
<i class="el-icon-upload el-icon--right"></i>
</el-button>
</el-upload>

上传组件用的是 elementUI 的 el-upload,前端一个表单中有多个这样的控件

save() {
let formData = new FormData();
formData.append("licenseNumberPhoto", this.$refs.basicInfo.$refs.licenseNumberPhoto.$children[0].fileList[0].raw);
formData.append("namePlatePhoto", this.$refs.basicInfo.$refs.namePlatePhoto.$children[0].fileList[0].raw);
formData.append("testReport", this.$refs.dpxx.$refs.testReport.$children[0].fileList[0].raw);
for(let key in this.form){
if(this.form.hasOwnProperty(key)){
formData.append(key,this.form[key])
}
}
this.$refs.form.validate(valid => {
if (true) {
addCar(formData).then((response) => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.form.disabled = true;
this.changeMode();
}
});
} else {
this.msgError('部分必填项未填写!');
}
})
},

用 formData 作为数据格式来传递给后端接口,此处传了三个文件。

 

2.后端

代码如下(示例):

/**
* 新增车辆信息、包含文件上传
*/
@PostMapping("/add")
public AjaxResult add(TzCar tzCar, HttpServletRequest request) {
// 返回此车辆的 rowGuid
int result = 0;
try {
result = tzCarService.insertTzCar(tzCar, request);
} catch (Exception e) {
logger.error(e.getMessage());
return AjaxResult.error(e.getMessage());
}
return toAjax(result);
}

接口使用 HttpServletRequest 来接收多个文件,逻辑是先将相关表单数据存入数据库,然后返回刚存入的这条数据的row_guid ,再将该row_guid和要存的文件关联起来存入数据库的。

注意这里的 TzCar tzCar 前面不要加 @RequestBody 注解,具体逻辑放在了 service 中。

@Override
public int insertTzCar(TzCar tzCar, HttpServletRequest request) throws Exception {
int result = tzCarMapper.insertTzCar(tzCar);
if (result > 0) {
String rowGuid = tzCar.getRowGuid();
// 文件大小的最大限制(500MB),单位为M
int fileMaxSize = 500 * 1024;
// 存储文件
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 取得request中的所有文件名
Iterator<String> iter = multiRequest.getFileNames();
while (iter.hasNext()) {
MultipartFile multipartFile = multiRequest.getFile(iter.next());
if (multipartFile != null) {
// 取得当前上传文件的参数名称
String fileParamName = multipartFile.getName();
int folderId = 0;
String originalFilename = multipartFile.getOriginalFilename();
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = multipartFile.getOriginalFilename();

int fileLength = (int) multipartFile.getSize();
DecimalFormat df = new DecimalFormat("#.00");
String size = df.format((((double) fileLength) / 1024 / 1024));
if (fileLength == 0) {
throw new Exception("没有文件");
} else if (multipartFile.getSize() > fileMaxSize * 1024) {
throw new Exception("文件大小限制" + size + "MB");
} else {
String contentType = fileExtension.substring(1);
if (!FileHelper.checkValidExt(contentType)) {
throw new Exception("不支持的文件类型");
}
byte[] content = multipartFile.getBytes();
// 32位随机编码
String fileGuid = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
FsFile fsFile = new FsFile(fileGuid, "ddzy_tz_car", rowGuid, folderId,
"", fileName, size, null, "1", null, null, null, null);
fileService.insertFile(fsFile, content);
}
}
}
}
return result;
}

主要就是从 request 中获取到多个文件和它们对应的 fieldName (因为这样才能确定某一个文件是哪种类型),获取到这些信息之后,后面的就简单了,无非就是将文件记录和文件内容存储起来。


总结

只能用 formData 格式进行传输,注意添加 @Transational 注解如果出现异常要回滚掉已经存入数据库中的数据。