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

[版权申明] 非商业目的注明出处可自由转载
出自: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

  • 86
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
你可以使用JavaBase64和Spring的MultipartFile实现Base64MultipartFile的工具。下面是一个示例代码: ```java import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.Base64; public class Base64ToMultipartFileUtil { public static MultipartFile base64ToMultipartFile(String base64) throws IOException { // 解码Base64字符串 byte[] decodedBytes = Base64.getDecoder().decode(base64); // 创建临时文件 String tempFileName = "temp.jpg"; // 可以根据需要修改文件名和File tempFile = new File(tempFileName); FileUtils.writeByteArrayToFile(tempFile, decodedBytes); // 创建MultipartFile对象 MultipartFile multipartFile = new MockMultipartFile(tempFile.getName(), tempFile.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(), new FileInputStream(tempFile)); // 删除临时文件 tempFile.delete(); return multipartFile; } } ``` 这个工具base64ToMultipartFile方法接受一个Base64字符串作为输入,并返回对应的MultipartFile对象。它首先将Base64字符串解码为字节数组,然后将字节数组写入临时文件中。接着使用MockMultipartFile创建MultipartFile对象,并指定文件名、原始文件名和文件型。最后,删除临时文件并返回MultipartFile对象。 请注意,这里使用的是Spring的MockMultipartFile,它是用于测试的模拟实现。在实际应用中,你需要根据自己的需求选择合适的MultipartFile实现。 希望这个工具对你有帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShuSheng007

亲爱的猿猿,难道你又要白嫖?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值