你的浏览器不支持canvas

做你害怕做的事情,然后你会发现,不过如此。

kkFileView源码修改

时间: 作者: 黄运鑫

本文章属原创文章,未经作者许可,禁止转载,复制,下载,以及用作商业用途。原作者保留所有解释权。


需要解决的问题

  • 1.限制预览文件大小
  • 2.已经转码过的文件,服务重启后再访问又重新转码

1.限制预览文件大小

  • 下载的源码版本为4.1.0-SNAPSHOTgitee项目地址
  • 在配置文件application.properties最后增加限制文件大小的参数
#预览文件大小限制(m):默认10,0不限制
preview.file.limit = ${KK_PREVIEW_FILE_LIMIT:10}
  • 打开系统参数类ConfigConstants,配置限制文件大小参数,增加代码如下
/**
 * @author: chenjh
 * @since: 2019/4/10 17:22
 */
@Component
public class ConfigConstants {
    //限制文件大小参数
    private static Integer previewFileLimit;

    //获取参数的方法
    public static Integer getPreviewFileLimit() {
        return previewFileLimit;
    }

    //从配置文件加载参数
    @Value("${preview.file.limit}")
    public void setPreviewFileLimit(Integer previewFileLimit) {
        setPreviewFileLimitValue(previewFileLimit);
    }

    public static void setPreviewFileLimitValue(Integer tifPreviewType) {
        ConfigConstants.previewFileLimit = tifPreviewType;
    }
}

  • 预览接口/onlinePreview增加限制文件大小的判断,接口代码如下
@GetMapping("/onlinePreview")
public String onlinePreview(String url, Model model, HttpServletRequest req) {
    String fileUrl;
    try {
        fileUrl = new String(Base64.decodeBase64(url), StandardCharsets.UTF_8);
    } catch (Exception ex) {
        String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
        return otherFilePreview.notSupportedFile(model, errorMsg);
    }
    FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl, req);
    model.addAttribute("file", fileAttribute);

    //限制文件大小
    try {
        if (fileUrl.startsWith("http")) {
            URL limitUrl = new URL(fileUrl);
            Integer previewFileLimit = ConfigConstants.getPreviewFileLimit();
            int contentLength = limitUrl.openConnection().getContentLength();
            if (previewFileLimit != null && previewFileLimit > 0 && (contentLength / 1024 / 1024) >= previewFileLimit) {
                return otherFilePreview.notSupportedFile(model, fileAttribute, "预览文件不能大于" + previewFileLimit + "m");
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    FilePreview filePreview = previewFactory.get(fileAttribute);
    logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType());
    return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
}

2.已经转码过的文件,服务重启后再访问又重新转码

  • 在预览文件时,系统会将下载和生成预览文件的路径缓存起来,当下次预览时直接使用缓存中的文件路径获取文件;但是系统重启或重新部署后,缓存会丢失,当再次预览相同文件时,又会重新转码
  • 解决方法有两种:

    1.系统启动后将已有文件重新加载到缓存中
    2.修改缓存机制,主要是两个类FileHandlerServiceCacheService,使用数据库或其他方法持久化存储

  • 因为预览文件量不大,这里使用的是第一种方法,在系统启动后加载已有文件,增加CacheRunner类如下:
package cn.keking.service.cache;

import cn.keking.config.ConfigConstants;
import cn.keking.service.FileHandlerService;
import cn.keking.utils.KkFileUtils;
import cn.keking.web.controller.OnlinePreviewController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * 将已有文件添加到缓存
 */
@Component
public class CacheRunner implements CommandLineRunner {
    private final Logger logger = LoggerFactory.getLogger(OnlinePreviewController.class);
    private static final String FILE_DIR = ConfigConstants.getFileDir();
    private final FileHandlerService fileHandlerService;

    public CacheRunner(FileHandlerService fileHandlerService) {
        this.fileHandlerService = fileHandlerService;
    }

    @Override
    public void run(String... args) {
        logger.info("加载已有文件:{}", "开始");
        String dir = FILE_DIR;
        // 如果dir不以文件分隔符结尾,自动添加文件分隔符
        if (!dir.endsWith(File.separator)) {
            dir = dir + File.separator;
        }

        logger.info("加载已有文件:路径:{}", dir);
        File dirFile = new File(dir);
        String[] list = dirFile.list();
        logger.info("加载已有文件:总数量:{}", list != null ? list.length : 0);
        int fileNum = 0;
        int directoryNum = 0;
        if (list != null) {
            Map<String, String> directoryMap = new HashMap<>();
            //文件缓存
            for (String fileName : list) {
                if (fileName.contains(".")) {
                    fileHandlerService.addConvertedFile(fileName, fileName);
                    fileHandlerService.addConvertedMedias(fileName, fileName);
                    //pdf对应的图片文件夹
                    String suffix = KkFileUtils.suffixFromFileName(fileName);
                    if (suffix.equals("pdf")) {
                        directoryMap.put(fileName.substring(0, fileName.lastIndexOf(".")), fileName);
                    }
                    fileNum++;
                }
            }

            //pdf对应的图片文件夹缓存
            for (String directoryName : list) {
                String fileName = directoryMap.get(directoryName);
                if (!directoryName.contains(".") && fileName != null) {
                    File file = new File(dir + directoryName + File.separator);
                    if (file.isDirectory()) {
                        //获取图片数量
                        String[] nameList = file.list();
                        if (nameList != null && nameList.length > 0) {
                            String path = dir + fileName;
                            fileHandlerService.addConvertedPdfImage(path, nameList.length);
                            directoryNum++;
                        }
                    }
                }
            }
        }
        logger.info("加载已有文件:成功文件数量:{}", fileNum);
        logger.info("加载已有文件:成功目录数量:{}", directoryNum);
        logger.info("加载已有文件:{}", "结束");
    }
}

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。