elementUI + Spring上传文件

elementUI + Spring上传文件

表单文件上传

【elementUI + Spring报错解决方案】Required request part ‘***‘ is not present

表单上传文件时需要去除@RequestBody

前端文件上传

  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;
        }
    }

}

posted @ 2023-11-28 14:42  ASini  阅读(34)  评论(0编辑  收藏  举报