elementUI + Spring上传文件
elementUI + Spring上传文件
表单文件上传
【elementUI + Spring报错解决方案】Required request part ‘***‘ is not present
前端文件上传
doApprove() {
const _this = this
// 创建表单对象
let formData = new FormData;
// 封装审批提交数据
formData.append("surveyId", this.approve.surveyId)
formData.append("accept", this.approve.accept)
formData.append("reason", this.approve.reason)
let attachments = this.approve.attachments
// 上传集合类型的文件,后端以List<MultipartFile>接收
attachments.forEach(attachment => formData.append('attachments', attachment))
// 请求审批接口
approve(formData).then(res => {
if (res.code === 200) {
_this.$modal.msgSuccess("审批完成")
_this.$router.go(-1)
} else {
_this.$modal.msgError("后台异常")
}
})
},
**在前端封装的时候,用
file.raw
,直接用file
并不能被后端解析到。
// 审批
export function approve(data) {
return request({
url: '/approval/approve',
method: 'post',
data: data
})
}
/*
如果传入的是对象,则会json序列化
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
不是对象就是表单
headers: { 'Content-Type': 'multipart/form-data' }
*/
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
后端接收
Base64上传文件MultipartFile
前端上传
// 上传图片方法
uploadPicture(pictureData, fileName) {
let _this = this
let objData = {
base64Str: pictureData, // 纯base64的图片信息
xxx: this.xxx, // 任务id
whatIs: this.whatIs, // 照片分区
fileNameFromHoney: fileName //照片带类型名称 例如 abc.png
}
// 开始加载中
this.isLoding = true
// 图片文件以base64形式请求后端接口(上传操作)
uploadFileByFormData(objData).then(res => {
let code = res.code
let fileUrl = res.fileUrl
if (code == 200) {
// 将上传成功的地址设置到图片集合中
_this.imgUrl = fileUrl
_this.$emit("update:imgUrl", fileUrl)
_this.$modal.msgSuccess("上传成功")
} else {
_this.$modal.msgError("上传失败")
}
// 上传操作结束后关闭加载中
_this.isLoding = false
})
},
// 图片文件上传方法
export function uploadFileByFormData(data) {
return request({
url: '/xxx/upload/mediaBase64',
method: 'post',
header: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: data
})
}
后端接收
- String 定义赋值Base64字符串在IDE编码中不支持,在浏览器发送后后端可以接收
@ApiOperation("采集上传照片Base64")
@PostMapping("/upload/mediaBase64")
public AjaxResult uploadMediaBase64(@NotNull String xxx, @NotNull String base64Str, @NotNull String whatIs, @NotNull String fileNameFromHoney) throws Exception {
// base64 转 MultipartFile
MultipartFile file = xxxService.getMultipartFileByBase64(base64Str, fileNameFromHoney);
assert file != null;
String pathFileName = xxxService.saveMedia(xxx, file, whatIs);
AjaxResult ajax = AjaxResult.success();
ajax.put("fileUrl", pathFileName);
return ajax;
}
public MultipartFile getMultipartFileByBase64(String fileStr, String fileNameFromHoney) {
// 转码
final String[] imageSuffix = {"jpg", "jpeg", "png"};
final String[] videoSuffix = {"mp4", "avi", "rmvb", "mov", "MOV"};
String[] split = fileNameFromHoney.split("\\.");
String fileNameSuffix = "";
//注意判断截取后的数组长度,数组最后一个元素是后缀名
if (split.length > 1) {
fileNameSuffix = split[split.length - 1];
}
final String[] base64Array = fileStr.split(",");
String dataUir, data;
if (base64Array.length > 1) {
dataUir = base64Array[0];
data = base64Array[1];
} else {
if (ArrayUtils.contains(imageSuffix, fileNameSuffix)) {
//根据你base64代表的具体文件构建
dataUir = "data:image/" + fileNameSuffix + ";base64,";
data = base64Array[0];
} else if (ArrayUtils.contains(videoSuffix, fileNameSuffix)) {
//根据你base64代表的具体文件构建
dataUir = "data:video/" + fileNameSuffix + ";base64,";
data = base64Array[0];
} else {
//根据你base64代表的具体文件构建
dataUir = "data:image/jpg;base64,";
data = base64Array[0];
}
}
String concat = dataUir.concat(data);
return Base64ToMultipartFile.base64ToMultipart(concat);
}
后端解析Base64字符串为文件的工具类
-
工具类使用前提是Base64字符串中含有
data:image/jpg;base64,
字样才可使用-
如果没有以
data:xxx;base64,
开头,则需要自行拼接字符串之后才可使用工具类 -
Base64开头字样示例 系统类别 data:image/jpeg;base64, data:image/jpg;base64, data:image/png;base64, data:video/;base64, data:video/mp4;base64, data:video/MOV;base64, IOS data:video/rmvb;base64, data:video/avi;base64,
-
package com.ruoyi.common.utils.file;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import java.io.*;
/**
* base64转MultipartFile
*/
public class Base64ToMultipartFile implements MultipartFile {
private final byte[] imgContent;
private final String header;
public Base64ToMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(";")[0];
}
@Override
public String getName() {
return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
}
@Override
public String getOriginalFilename() {
return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
}
@Override
public String getContentType() {
return header.split(":")[1];
}
@Override
public boolean isEmpty() {
return imgContent == null || imgContent.length == 0;
}
@Override
public long getSize() {
return imgContent.length;
}
@Override
public byte[] getBytes() throws IOException {
return imgContent;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(imgContent);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
new FileOutputStream(dest).write(imgContent);
}
public static MultipartFile base64ToMultipart(String base64) {
try {
String[] baseStrs = base64.split(",");
BASE64Decoder decoder = new BASE64Decoder();
byte[] b = new byte[0];
b = decoder.decodeBuffer(baseStrs[1]);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
return new Base64ToMultipartFile(b, baseStrs[0]);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
尽量的奔跑