jeecgBoot框架前端富文本组件多图片内容渲染过慢

问题出现原因

本人业务需求需要使用jeecgBoot的前端富文本组件<kindeditor>

<a-collapse-panel id="one3" key="one3" header="主要研究内容">
            <kindeditor
              id="kindex2"
              height="550px"
              @kindeditorChange="(val) => form.jobContent = val "
              :content="form.jobContent"
            />
          </a-collapse-panel>

在项目上线后出现了几个问题:

  • 当存放的内容过多后报错提示插入过长的数据,经过定位处理为jeecgBoot代码生成器生成的数据库表中MySQL存放富文本的字符串是text,只需要修改为longtext即可,text字段类型的字节限制为65535字节,longtext字段类型的字节限制为2147483647字节

  • 虽然完美解决了因为数据量大而插入数据失败的问题,但是又出现了一个新的问题,由于数据量巨大,在前端打开富文本组件时渲染加载的时间特别长,可能有10秒左右,这在系统的使用是完全不能接受的。于是经过我的分析,我发现jeecgBoot的富文本组件在保存图片时是保存的图片对应的Base64编码
    在这里插入图片描述
    这样来方便图片渲染。如果图片少可能不会有什么影响,但是不巧的是我的项目使用场景中需要考虑大量的图片问题,所以就很慢。
    解决办法:我想到将图片保存我们公司的minIO服务器,再将富文本字符串中图片的Base64编码保存形式替换成<img src="/jeecg-boot/**/**/**/*****.jpg" alt="" />这样就大大减少了数据量,虽然想到解决办法但是实现起来有几个麻烦的地方.

  • 从富文本字符串中定位到<img>标签抓取Base64编码

  • 转换为对应的图片文件流,调用minIO保存接口

  • 拿到返回的图片url地址,替换富文本字符串的<img>标签
    废话不多说直接上代码

 private Pattern pattern = Pattern.compile("<img\\s+[^>]*?src=\"data:image/[a-zA-Z]*;base64,([^\"\\s]+)\"");


public String replaceImgBase64ToUrl(String richText){
        if(StringUtils.isEmpty(richText)){
            return richText;
        }
        // 匹配 img 标签中的 base64 数据
        //Pattern pattern = Pattern.compile("<img\\s+src=\"data:image/[a-zA-Z]*;base64,([^\"]+)\"");
        //Pattern pattern = Pattern.compile("<img\\s+[^>]*src=\"data:image/[a-zA-Z]*;base64,([^\"]+)\"");
        Matcher matcher = pattern.matcher(richText);

        while (matcher.find()) {
            String base64Data = matcher.group(1);
            byte[] imageBytes = Base64.decodeBase64(base64Data);

            MinioClient minioClient = MinioClient.builder().endpoint(minioUrl).credentials(minioName, minioPass).build();
            // 上传图片到 MinIO
            String objectName = "zt"+ System.currentTimeMillis() + RandomUtil.randomString(10) + ".jpg";
            try (InputStream inputStream = new ByteArrayInputStream(imageBytes)) {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object("img/"+objectName)
                        .stream(inputStream, inputStream.available(), -1)
                        .build());
            } catch (Exception e) {
                throw new TipInfoException("富文本上传图片到minIO出现异常!!");
            }
            // 替换富文本字符串中的 img 标签
            String imageUrl = "/jeecg-boot/***/***/***/"+ objectName;
            richText = richText.replace("data:image/png;base64," + base64Data, imageUrl);
        }
        return richText;
    }

完美。。但是这样做又又有一个衍生问题,我们需要写的导出word文件
导出时富文本字符串不能将<img src="/jeecg-boot/**/**/**/*****.jpg" alt="" />转换成对应的图片,所以我们又需要逆向思考

  • 先根据富文本中<img>标签中的url地址去minIO服务器获取图片文件流
  • 文件流转换会对应的Base64编码
  • 替换富文本字符串中的<img>标签,换成Base64编码的标签
  • 然后再执行我得word导出
    同样废话不多说直接上代码
private Pattern pattern = Pattern.compile("<img\\s+[^>]*?src=\"(/jeecg-boot/**/**/**/[^/\">]+)\"[^>]*>");


public String replaceUrlToImgBase64(String richText) {
       if (StringUtils.isEmpty(richText)) {
           return richText;
       }

       // 匹配 img 标签中的图片 URL
       Matcher matcher = pattern.matcher(richText);

       while (matcher.find()) {
           String imgTag = matcher.group(0); // 获取匹配到的整个 img 标签
           String imageUrl = matcher.group(1); // 获取匹配到的图片 URL

           int lastIndex = imageUrl.lastIndexOf('/');
           String imageName = imageUrl.substring(lastIndex + 1);

           try {
               MinioClient minioClient = MinioClient.builder().endpoint(minioUrl).credentials(minioName, minioPass).build();

               // 下载文件
               InputStream inputStream = minioClient.getObject(
                       GetObjectArgs.builder().bucket(bucketName).object("img/" + imageName).build()
               );

               ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
               byte[] buffer = new byte[4096];
               int bytesRead;
               while ((bytesRead = inputStream.read(buffer)) != -1) {
                   outputStream.write(buffer, 0, bytesRead);
               }
               String base64Data = Base64.encodeBase64String(outputStream.toByteArray());

               // 替换富文本字符串中的图片 URL
               richText = richText.replace(imageUrl, "data:image/png;base64," + base64Data);
           } catch (Exception e) {
               throw new TipInfoException("word导出图片转换错误!" + e.toString());
               // 处理异常情况
           }
       }

       return richText;
   }

又一次完美解决问题,写完收工!!^ _ ^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值