改公司一个app,他们用canvas做手动签名,上传过程中后端用MultipartFile接收,接收到的文件没后缀名。
后面百度知道base64头部有文件类型,需要在后端处理。
大概思路就是base64转MultipartFile然后在调用以前文件上传的方法。
======================================前端
let path = res.tempFilePath;
uni.showLoading({title: '上传中...',mask: true});//遮罩层
uni.uploadFile({
url: request.baseUrl + '/xxController/uploadImg?fId=' + that.id,
header: {
'token': that.$store.state.token
},
file: path,//修改前的参数传递
name: 'file',
formData: {//修改后参数传递:将文件base64通过额外参数传递到后台
'base64Str':path
},
success: (res) => {
path变量在前端打印的格式:
头部data:image/png;base64,
文件内容去除头部部分
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtoAAAMQCAYAAAAZ6sJVAAAgAElEQVR4Xu3dC9AvaV0f+G+8RWuAGQRFkyhQtVmjRkHxVonZmaktozUagTW73IwMK1fRAGIC7iLDJcmiRsBNMMCiDK4gWDGAF9aNW8uQ1ZRGkEtQd7Nby4yuishlQEy8s/WD/ytnDud9+/Lv/nf305+uOjXodD...
======================================后端
第一步:我们需要一个base64转MultipartFile的类【直接拷贝用就行】
package com.synda.cgegov.utils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
public class BASE64DecodedMultipartFile implements MultipartFile {
private final byte[] imgContent;
private final String header;
public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
this.imgContent = imgContent;
this.header = header.split(";")[0];
}
@Override
public String getName() {
// TODO - implementation depends on your requirements
return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
}
@Override
public String getOriginalFilename() {
// TODO - implementation depends on your requirements
return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
}
@Override
public String getContentType() {
// TODO - implementation depends on your requirements
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);
}
}
第二步:接收base64文件调用第一步方法转MultipartFile
其中String baseValue=base64Str.replaceAll("","+");这句必不可少,否则有时候文件打开会说格式不支持;
字节数组创建下一句的"data:image/png;base64,","")可以根据自己base64串头改变
/**
* base64转MultipartFile
*/
public MultipartFile base64ToMultipart(HttpServletRequest request, String fId){
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
String base64Str=multipartRequest.getParameter("base64Str");
if(!"".equals(base64Str)){
try {
String baseValue = base64Str.replaceAll(" ", "+");
BASE64Decoder decoder = new BASE64Decoder();
byte[] bytes = new byte[0];
bytes = decoder.decodeBuffer(baseValue.replace("data:image/png;base64,",""));
for (int i = 0; i < bytes.length; ++i) {
if (bytes[i] < 0) {
bytes[i] += 256;
}
}
//将文件输出到本地看传递过来的文件base64格式是否正确
//FileOutputStream fos = new FileOutputStream ("D:\\test.png");
//fos.write(bytes);
//fos.flush();
//fos.close();
return new BASE64DecodedMultipartFile(bytes,base64Str.split(",")[0]);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
return null;
}
第三步:调用方法上传到ftp
这里就简单写个上传
public Result addSignInfos(HttpServletRequest request, String fId) throws FileNotFoundException {
MultipartFile file=base64ToMultipart(request,fId);
//return addDish(file,fId);
//用于测试文件流上传到ftp
InputStream in= null;
try {
in = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
boolean flag = uploadFile("ftpip", 21, "用户名", "密码", "上传前段目录", "上传的后段目录", "16.png", in);
return Result.me().OK();
}
public static boolean uploadFile(String host, int port, String username, String password, String basePath,
String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(host, port);// 连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
//切换到上传目录
if (!ftp.changeWorkingDirectory(basePath+filePath)) {
//如果目录不存在创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir)) continue;
tempPath += "/" + dir;
if (!ftp.changeWorkingDirectory(tempPath)) {
if (!ftp.makeDirectory(tempPath)) {
return result;
} else {
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.setControlEncoding("UTF-8");
//上传文件
ftp.enterLocalPassiveMode();
if (!ftp.storeFile(new String(filename.getBytes("UTF-8"),"iso-8859-1"),input)) {
return result;
}
input.close();
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
为了研究这个,搜了10多篇文章,从没有思路到最终解决,感谢各位大牛的帖子!
主要参考:
https://blog.csdn.net/cd420928908/article/details/82761887#comments_13830678
https://blog.csdn.net/weixin_41162263/article/details/81876346