base64字符串传递文件
IPFS
前两天开发一个功能中涉及文件上传/下载功能,这是非常常见的一个功能,一般都是前端通过multipart/form-data的模式传递给后端,后端则通过MultipartFile接收即可。 但这次遇到一个问题,前端请求先到C端(所谓C端可以理解为服务端的入口层,所有请求都会先到达C端,再由C端下发给各种不同的服务,这样的好处是对于前端来说,不需要跟一堆的后端部门对接,只要跟C端对接就好了) 我们服务间的调用都是通过feign这个http框架,这也是跟随spring cloud一起火起来的一个框架。但也就是这个框架导致从C端通过feign透传调用下游的服务一直失败,各种问题。以往别的同事都是在C端直接把文件存到阿里的oss,然后获取文件的url,再把url传给下游服务,下游服务再通过url从阿里oss下载后再处理。 但我觉得这样做太复杂了,C端就不应该有额外的业务逻辑,尽量透传是最好的,所以一心想直接通过feign传文件。 当尝试了多种写法都无济于事的时候,突然想到百度的图片识别API不是把图片转成base64字符串传递给后台的嘛,于是我就想在C端通过MultipartFile接收后, 转成byte数组,再将byte数组转成base64字符串,再通过feign传base64字符串就毫无问题了。同样的下载文件也是如此,先从下游服务生成文件后,先转成base64字符串返回给C端, C端再转成文件直接通过httpServletResponse输出文件流。 这是C端将MultipartFile转成base64的代码段,关键是把文件名和类型都传递下去了,下游生成MultipartFile的时候需要 ````java @PostMapping("/upload") public ResultContentResponse<Long> upload(@RequestParam("file") MultipartFile file, @RequestParam("scene") String scene, @RequestParam("orgId") Integer orgId) throws IOException { BankCardValideUploadRequest req = new BankCardValideUploadRequest(); //String encode = new BASE64Encoder().encode(file.getBytes()); String encode = Base64.encodeBase64String(file.getBytes()); req.setFile(encode); req.setScene(scene); req.setOrgId(orgId); req.setFileContentType(file.getContentType()); req.setFileName(file.getOriginalFilename()); BasicResponse<Long> upload = bankCardValidClient.upload(req); } ```` 这是下游的代码,把base64转回MultipartFile,BASE64DecodedMultipartFile是自己实现一个MultipartFile, 需要用到文件名和类型 ````java byte[] bytes = Base64.decodeBase64(request.getFile()); MultipartFile multipartFile = new BASE64DecodedMultipartFile(bytes, request.getFileName(), request.getFileContentType()); ```` ````java public class BASE64DecodedMultipartFile implements MultipartFile { private byte[] imgContent; private String fileName; private String contentType; public BASE64DecodedMultipartFile(byte[] imgContent, String fileName, String contentType) { this.imgContent = imgContent; this.fileName = fileName; this.contentType = contentType; } @Override public String getName() { return fileName; } @Override public String getOriginalFilename() { return fileName; } @Override public String getContentType() { return contentType; } @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); } } ```` 下载的时候将excel文件转成ByteArrayOutputStream ````java ByteArrayOutputStream byteArrayOutputStream = ee.writeFileToByte(); String encode = Base64.encodeBase64String(byteArrayOutputStream.toByteArray()); result.setFile(encode); result.setFileName(fileName); ```` 再由C端输出excel ````java @PostMapping("/result/download") public void reslutDownload(@RequestBody @Valid BankCardDoValideRequest request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws Exception { BasicResponse<BankCardDoValideDto> bankCardDoValideDtoBasicResponse = bankCardValidClient.reslutDownload(request); BankCardDoValideDto data = bankCardDoValideDtoBasicResponse.getData(); OutputStream os = null; try { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("UTF-8"); response.setDateHeader("Expires", 0L); response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); response.setHeader("Pragma", "no-cache"); if (httpServletRequest.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) { response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(data.getFileName(), "UTF-8")); } else { response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode(data.getFileName(), "UTF-8")); } os = response.getOutputStream(); byte[] bytes = Base64.decodeBase64(data.getFile()); Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)); wb.write(os); } finally { if (os != null) { os.flush(); os.close(); } } } ````
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!