需要解决的问题
- 1.限制预览文件大小
- 2.已经转码过的文件,服务重启后再访问又重新转码
1.限制预览文件大小
- 下载的源码版本为
4.1.0-SNAPSHOT
,gitee项目地址 - 在配置文件
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.修改缓存机制,主要是两个类FileHandlerService
和CacheService
,使用数据库或其他方法持久化存储 - 因为预览文件量不大,这里使用的是第一种方法,在系统启动后加载已有文件,增加
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("加载已有文件:{}", "结束");
}
}