polkallen avatar

base64字符串传递文件

polkallen

Published: 09 May 2022 › Updated: 09 May 2022base64字符串传递文件

base64字符串传递文件

image.png

前两天开发一个功能中涉及文件上传/下载功能,这是非常常见的一个功能,一般都是前端通过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的时候需要

@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, 需要用到文件名和类型

byte[] bytes = Base64.decodeBase64(request.getFile());
MultipartFile multipartFile = new BASE64DecodedMultipartFile(bytes, request.getFileName(), request.getFileContentType());
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

ByteArrayOutputStream byteArrayOutputStream = ee.writeFileToByte();
String encode = Base64.encodeBase64String(byteArrayOutputStream.toByteArray());
result.setFile(encode);
result.setFileName(fileName);

再由C端输出excel

@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();
        }
    }
}

Leave base64字符串传递文件 to:

Written by

在上海务工,分享生活,相互点赞

Read more #hive-105017 posts


Best Posts From polkallen

We have not curated any of polkallen's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From polkallen