自学内容网 自学内容网

Java 处理base64文件上传

场景:

        在系统内有一个类似于公告的模块,如果里面添加的文章不是选择富文本上传图片的方式,而是选择复制别的文章直接粘贴到系统内的富文本,里面的图片就不会是url,而是图片的base64格式,这样会导致数据库存储压力过大,数据接口处理缓慢等问题...

解决:

        前端在进行检索校验,如果检测到了base64格式的文件就单独去走后台的接口,后台需要出一个单独处理base64文件上传的接口,将base64数据转化成文件进行上传,然后返回存储目标地址的url路径返回给前端,让前端在富文本里面去进行展示

代码:

controller

/**
     * 通用上传请求(单个)
     */
    @ApiOperation(value = "上传文件(仅接收 Base64)")
    @PostMapping("/uploadBase64")
    public Base64UploadResponse uploadFileBase64(@RequestBody String base64Data)
    {
        // 定义数据的返回。因为前端处理富文本的时候用了一个单独的框架,需要按照那个框架进行相应的数据返回,所以才怎么写的
        Base64UploadResponse.Data data = new Base64UploadResponse.Data("", "", "","图片编码不能为空!");
        // 返回值code定义
        int resultCode = 0;
        // 非空判断
        if(base64Data.isEmpty()){
            // 异常返回
            data = new Base64UploadResponse.Data("", "", "","图片编码不能为空!");
            return new Base64UploadResponse(resultCode,data);
        }
        // 图片上传
        Map<String, String> returnFileBase64 = ossUploadFileUtils.uploadPublicBase64(base64Data);
        // 返回值判断
        if(returnFileBase64.isEmpty()){
            data = new Base64UploadResponse.Data("", "", "","图片编码解析或上传异常!");
        }else{
            resultCode = 200;
            data = new Base64UploadResponse.Data(returnFileBase64.get("url"), returnFileBase64.get("fileName"), "","图片上传成功!");
        }
        // 返回给前端
        return new Base64UploadResponse(resultCode,data);
    }

返回对象:


/**
 * 操作消息提醒
 */
public class Base64UploadResponse {
    private int errno; // 错误码,必须是数字
    private Data data; // 嵌套的 data 对象

    // 内部静态类,用于 data 字段
    public static class Data {
        private String url; // 图片 URL,必须
        private String alt; // 图片描述文字,非必须
        private String href; // 图片链接,非必须
        private String msg; // 消息,非必须

        // 构造函数
        public Data(String url, String alt, String href, String msg) {
            this.url = url;
            this.alt = alt;
            this.href = href;
            this.msg = msg;
        }

        // Getters 和 Setters
        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getAlt() {
            return alt;
        }

        public void setAlt(String alt) {
            this.alt = alt;
        }

        public String getHref() {
            return href;
        }

        public void setHref(String href) {
            this.href = href;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }
    }

    // 构造函数
    public Base64UploadResponse(int errno, Data data) {
        this.errno = errno;
        this.data = data;
    }

    // Getters 和 Setters
    public int getErrno() {
        return errno;
    }

    public void setErrno(int errno) {
        this.errno = errno;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }
}

utils:

/**
     * base64文件格式数据转换
     */
    public Map<String, String> uploadPublicBase64(String base64Data) {
        try {
            // 检查是否包含前缀,并移除它
            if (base64Data.startsWith("data:image/png;base64,")) {
                base64Data = base64Data.replace("data:image/png;base64,", "");
            }
            // 解码 Base64 数据
            byte[] fileData = Base64.getDecoder().decode(base64Data);
            // 自动生成文件名
            String generatedFilename = "file_" + System.currentTimeMillis() + ".bin";
            // 将字节数据转换为 MultipartFile
            MultipartFile file = new Base64ToMultipartFile(fileData, generatedFilename);
            // 将base64转化成对应的上传文件的格式就可以走系统内的上传方法了,然后将返回的数据返回给前端就可以正常展示了
            Map<String, String> stringStringMap = uploadPublic(file);
            return stringStringMap;
        } catch (Exception e) {
            return null;
        }
    }

import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Base64ToMultipartFile implements MultipartFile {

    private final byte[] fileContent;
    private final String originalFilename;

    public Base64ToMultipartFile(byte[] fileContent, String originalFilename) {
        this.fileContent = fileContent;
        this.originalFilename = originalFilename;
    }

    @Override
    public String getName() {
        return originalFilename;
    }

    @Override
    public String getOriginalFilename() {
        return originalFilename;
    }

    @Override
    public String getContentType() {
        // 根据需要返回 MIME 类型
        return "application/octet-stream";
    }

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

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

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

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

    @Override
    public void transferTo(java.io.File dest) throws IOException {
        throw new UnsupportedOperationException("This operation is not supported.");
    }
}

注:

       !数据转码异常问题

# 我在别的系统同样也使用该功能,发现我的
MultipartFile file = new Base64ToMultipartFile(fileData, generatedFilename);
# 不是每次都能正常转化,所以我又切换了一种方法

     /**
     * base64文件格式数据转换
     */
                                        #  这个参数可以不用管,没什么作用
    public static String uploadPublicBase64(String filePath, String base64Data) {
        try {
            // 检查是否包含前缀,并移除它
            if (base64Data.startsWith("data:image/png;base64,")) {
                base64Data = base64Data.replace("data:image/png;base64,", "");
            }
            // 解码 Base64 数据
            byte[] fileData = Base64.getDecoder().decode(base64Data);
            // 自动生成文件名
            String generatedFilename = "file_" + System.currentTimeMillis() + ".png"; // 假设是PNG文件
            // 创建 MultipartFile(使用 MockMultipartFile)
            MockMultipartFile file = new MockMultipartFile(
                    "file",                    // 参数名
                    generatedFilename,               // 文件名
                    "image/png",                     // 文件类型
                    fileData                         // 文件内容
            );
            // 上传文件逻辑
            String result = upload(filePath, file); // 调用上传方法
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

返回结果:

正常传入base64就会返回上传后对应的图片的信息。


原文地址:https://blog.csdn.net/ord_D/article/details/144758779

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!