如何将base64图像数据以图片的形式上传到云存储obs中

举报
穆雄雄 发表于 2022/11/29 16:18:14 2022/11/29
【摘要】 大家好,我是雄雄。欢迎关注微信公众号:雄雄的小课堂。今天分享个方法,如标题所示:在日常开发中,我们经常会有这样的需求,将前台拿到的base64图像格式的数据,上传到云存储服务器上,比如阿里云oss,华为云obs等,今天我们就来看看,拿到数据后,我们如何上传。首先需要一个工具类BASE64DecodedMultipartFileUtil:package org.jeecg.common.uti...

大家好,我是雄雄。欢迎关注微信公众号:雄雄的小课堂。

在这里插入图片描述
今天分享个方法,如标题所示:

在日常开发中,我们经常会有这样的需求,将前台拿到的base64图像格式的数据,上传到云存储服务器上,比如阿里云oss,华为云obs等,今天我们就来看看,拿到数据后,我们如何上传。

首先需要一个工具类BASE64DecodedMultipartFileUtil

package org.jeecg.common.util;

import org.jetbrains.annotations.NotNull;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

public class BASE64DecodedMultipartFileUtil implements MultipartFile {

    private final byte[] imgContent;
    private final String header;

    public BASE64DecodedMultipartFileUtil(byte[] imgContent, String header) {
        this.imgContent = imgContent;
        this.header = header.split(";")[0];
    }

    @NotNull
    @Override
    public String getName() {
        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
    }

    @Override
    public String getOriginalFilename() {
        return System.currentTimeMillis() + (int) (Math.random() * 10000) + "." + header.split("/")[1];
    }

    @Override
    public String getContentType() {
        return header.split(":")[1];
    }

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

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

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

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

    @Override
    public void transferTo(@NotNull File dest) throws IOException, IllegalStateException {
        new FileOutputStream(dest).write(imgContent);
    }

}

然后我们写个接口,接收前台传过来的值,控制器的代码如下:

/**
     * 主要用于小程序上传
     *
     * @return 地址
     */
    @PostMapping(value = "/uploadFile")
    public String uploadBase64(@RequestBody JSONObject json) {
        String bizPath = "applets/images/";
        JSONArray jsonArray = json.getJSONArray("imageaddr");
        JSONObject object = jsonArray.getJSONObject(0);
        String [] baseStr = object.getString("url").split(",");
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b = new byte[0];
        try {
            b = decoder.decodeBuffer(baseStr[1]);
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        MultipartFile file = new BASE64DecodedMultipartFileUtil(b, baseStr[0]);
        String url  = CommonUtils.upload(file, bizPath, uploadType);
        url = url.substring(url.indexOf("applets/images/"));
        return url;
    }

该接口传递的参数格式是这样的:

[{"url":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABgYAAAHyCAYAAAAgDXWwAAAgAElEQVR4AezBWc+taWIe5Ot+3rW+aQ81dPVs4C............."}]

所以我们在前端传参数的时候,一定要注意。

剩下的就都是走的jeecg-boot自带的文件上传的方法了,我这边也贴上来吧。

CommonUtils类中的upload方法

/**
     * 统一全局上传
     *
     * @Return: java.lang.String
     */
    public static String upload(MultipartFile file, String bizPath, String uploadType) {
        String url = "";
        try {
            if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
                url = MinioUtil.upload(file, bizPath);
            }  else if (CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)) {
                url = OssBootUtil.upload(file, bizPath);
            }else{
                url = ObsBootUtil.upload(file, bizPath);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return url;
    }

ObsBootUtil中文件上传的方法:

    /**
     * 文件上传
     *
     * @param file    文件
     * @param fileDir fileDir
     * @return 路径
     */
    public static String upload(MultipartFile file, String fileDir) throws Exception {
        return upload(file, fileDir, null);
    }

调用的是下面的upload方法

/**
     * 上传文件至华为云 OBS
     * 文件上传成功,返回文件完整访问路径
     * 文件上传失败,返回 null
     *
     * @param file    待上传文件
     * @param fileDir 文件保存目录
     * @return oss 中的相对文件路径
     */
    public static String upload(MultipartFile file, String fileDir, String customBucket) throws Exception {
        //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
        FileTypeFilter.fileTypeFilter(file);
        //update-end-author:liusq date:20210809 for: 过滤上传文件类型

        String filePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        StringBuilder fileUrl = new StringBuilder();
        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(customBucket)) {
            newBucket = customBucket;
        }
        try {
            //判断桶是否存在,不存在则创建桶
            if (!ossClient.headBucket(newBucket)) {
                ossClient.createBucket(newBucket);
            }
            // 获取文件名
            String orgName = file.getOriginalFilename();
            if ("".equals(orgName) || orgName == null) {
                orgName = file.getName();
            }
            orgName = CommonUtils.getFileName(orgName);
            String fileName = !orgName.contains(".")
                    ? orgName + "_" + System.currentTimeMillis()
                    : orgName.substring(0, orgName.lastIndexOf("."))
                    + "_" + System.currentTimeMillis()
                    + orgName.substring(orgName.lastIndexOf("."));
            if (!fileDir.endsWith(SymbolConstant.SINGLE_SLASH)) {
                fileDir = fileDir.concat(SymbolConstant.SINGLE_SLASH);
            }
            //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
            fileDir = StrAttackFilter.filter(fileDir);
            //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
            fileUrl.append(fileDir).append(fileName);

            filePath = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH + fileUrl;

            PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
            // 设置权限(公开读)
//            ossClient.setBucketAcl(newBucket, CannedAccessControlList.PublicRead);
            if (result != null) {
                log.info("------OSS文件上传成功------" + fileUrl);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return filePath;
    }

然后就上传OK啦,接口返回的是该文件的的图片地址,直接放数据库中就可以了。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。