当前位置: 首页 > 工具软件 > Base > 使用案例 >

Base64如何转MultipartFile(对流行实现类BASE64DecodedMultipartFile的修正)

萧奇
2023-12-01

[版权申明] 非商业目的注明出处可自由转载
出自:shusheng007

概述

前两天遇到一个需要将Base64转换为MultipartFile的需求,于是网上搜索了一下,千篇一律的都是同一篇从国外网站搬运过来的那一篇文章,然后没有任何解释,没有任何改动,里面很多需要改进的地方也没有说,就是一顿猛抄。哎,国内IT与国外确实还有较大的差距,国人还需要努力,首先态度上就应该改变。

鉴于此,我准备简单整理一下这块,力争使我们后辈既知其然,也知其所以然!后浪加油浪,要狂狼!

网上的例子

真的是一顿猛抄,你抄我我抄你,你在搜索引擎上搜索BASE64DecodedMultipartFile就能看见国人抄的都是同一篇文章了。你看下面的使用方式也是一顿猛抄,也不管为什么这么写,这么写对不对。还有人提问:base64解码后的byte[]数组什么要加256啊?看看把我们祖国的下一代IT工作者困惑成了啥样?

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]);

我初次看到网上BASE64DecodedMultipartFile类及其使用方式感觉到莫名其妙,主要是因为其是依据带DataURI的Base64字符串写的,要是你获得是纯base64数据,相信你已经懵逼了。

那个使用方式也值得商榷,当从base64解码成byte[]后,却要循环检查是否包含负值然后加256也是莫名其妙。解码后的byte[]数组已经是Base64代表的具体内容(图片,文字…)的二进制表示形式了,直接使用即可不知道为什么还要变换。

此处原来有误,感谢评论区小伙伴提醒

BASE64Decoder明确被Java官方标记为不推荐使用,将来可能被删除或修改,也没人管。

我想了一下还是写一篇文章吧,也算是为纠正这个话题的一点努力,希望有缘人看一看到,修正这个base64转MultipartFile在中国互联网上的流毒。

实现类

由于MultipartFile是一个接口,而Java类库没有提供一个将Base64转换为MultipartFile的合适的实现类,所以我们需要自己实现这个接口。实现过程中有几点需要注意。

首先确定你要处理的base64数据是否携带DataURI, 像下面这样

data:image/jpeg;base64,/9j/4AA...

如果带我们就可以从其中获得文件的contentType,文件扩展名等。

  1. getOriginalFilename()方法最好带上文件的扩展名,例如你的是图片的话,带上.jpg .png 之类的。
  2. getContentType()方法返回其内容类型,例如image/png

下面是我改进的一个实现类


/**
 * Created by ShuSheng007
 * <p>
 * author     : ShuShneg007
 * date       : 2021/6/25 19:09
 * description:
 */
public class Base64ToMultipartFile implements MultipartFile {
    private final byte[] fileContent;

    private final String extension;
    private final String contentType;


    /**
     * @param base64
     * @param dataUri     格式类似于: data:image/png;base64
     */
    public Base64ToMultipartFile(String base64, String dataUri) {
        this.fileContent = Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
        this.extension = dataUri.split(";")[0].split("/")[1];
        this.contentType = dataUri.split(";")[0].split(":")[1];
    }

    public Base64ToMultipartFile(String base64, String extension, String contentType) {
        this.fileContent = Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
        this.extension = extension;
        this.contentType = contentType;
    }

    @Override
    public String getName() {
        return "param_" + System.currentTimeMillis();
    }

    @Override
    public String getOriginalFilename() {
        return "file_" + System.currentTimeMillis() + "." + extension;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public boolean isEmpty() {
        return fileContent == null || fileContent.length == 0;
    }

    @Override
    public long getSize() {
        return fileContent.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return fileContent;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(fileContent);
    }

    @Override
    public void transferTo(File file) throws IOException, IllegalStateException {
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(fileContent);
        }
    }

}

使用

唯一需要注意的是,如果你要转换的base64是不带DataURI的,那你有两个选择,

  • 第一种方法按照实际情况创建一个dataUri,如下面代码所示。

 public Boolean uploadFile(String base64) {
     final String[] base64Array = base64.split(",");
     String dataUir, data;
     if (base64Array.length > 1) {
         dataUir = base64Array[0];
         data = base64Array[1];
     } else {
         //根据你base64代表的具体文件构建
         dataUir = "data:image/jpg;base64";
         data = base64Array[0];
     }
     MultipartFile multipartFile = new Base64ToMultipartFile(data, dataUir);
     ...
     return true;
 }
  • 第二种方法就是采用如下构造函数
Base64ToMultipartFile(String base64, String extension, String contentType)

总结

以上就是全部内容,希望可以对需要的人有所帮助,凡事多挖一点,你就会比别人更牛一点。

关于Base64算法的文章推荐阅读 让你彻底理解Base64算法(Base64是什么,Base64解决什么问题,Base64字符串末尾的=是什么)

又到了点赞支持的时候了,这篇文章的意义我觉得与其他文章不同,大家多支持,让我们一起扭转网上那些错误的抄袭文章,早点回家抱孩子,陪老婆…

源码

一如既往,你可以在GitHub上找到本文的源码:Base64ToMultipartFile

 类似资料: