前言
目前小程序的 wx.uploadFile 方法,还不支持批量上传,只能使用循环一个一个进行上传,对于某些特定需求,或者想节约带宽的时候,显然这种方式还是满足不了,下面提供一种方案解决批量上传问题,虽然不是最优方案,但是能实现一次请求上传多个图片。
思路
小程序批量选择完图片后,把图片转换为base64编码,然后push到数组当中,然后通过 wx.request 请求服务端接口,服务端接口对其进行base64解码,最好转换为file文件流。
小程序端代码
/** * 通过wx.chooseImage选择后的fileList * @param {*} fileList */ upPic: function (fileList) { let file = [] for(let i=0;i<fileList.length;i++){ const fileSystemManager = wx.getFileSystemManager() const data = fileSystemManager.readFileSync(fileList[i].path,'base64') file.push('data:image/jpeg;base64,'+data) } wx.request({ url: 'http://192.168.3.78:8080/sh-api-videos/video/selected/upload', data: { fileList: file }, method: 'POST', header: { 'content-type': 'application/json' }, success (res) { console.log(res.data) } }) }
服务端代码(java示例)
/** * 接受fileList的controller方法 * @param upload * @throws IOException */ @PostMapping(value="/upload",consumes=MediaType.APPLICATION_JSON_VALUE) @SaveLog public void upload(@RequestBody @Valid Upload upload) throws IOException { List<String> fileList = upload.getFileList(); for (int i=0;i<fileList.size();i++) { String str = fileList.get(i); MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(str); System.out.println(multipartFile.getName()); System.out.println(multipartFile.getOriginalFilename()); approvalFile(multipartFile); } }
// 此处是保存文件到本地,不使用可忽略 public void approvalFile( MultipartFile filecontent){ OutputStream os = null; InputStream inputStream = null; String fileName = null; try { inputStream = filecontent.getInputStream(); fileName = filecontent.getOriginalFilename(); } catch (IOException e) { e.printStackTrace(); } try { String path = "/Users/whao/tmp/upload/"; // 2、保存到临时文件 // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流保存到本地文件 File tempFile = new File(path); if (!tempFile.exists()) { tempFile.mkdirs(); } os = new FileOutputStream(tempFile.getPath() + File.separator + fileName); // 开始读取 while ((len = inputStream.read(bs)) != -1) { os.write(bs, 0, len); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { // 完毕,关闭所有链接 try { os.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
服务端代码 (Upload实体类)
package com.sh.api.video.model; import java.util.List; public class Upload { private List<String> fileList; public List<String> getFileList() { return fileList; } public void setFileList(List<String> fileList) { this.fileList = fileList; } }
服务端代码 (base64转换为MultipartFile工具类)
package com.sh.api.video.utils; import org.springframework.web.multipart.MultipartFile; import sun.misc.BASE64Decoder; import java.io.*; /** * base64转MultipartFile */ 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文件 * * @param base64 * @return */ 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 BASE64DecodedMultipartFile(b, baseStrs[0]); } catch (IOException e) { e.printStackTrace(); return null; } } }