Compare commits

...

9 Commits

Author SHA1 Message Date
陈精华
9786fa8275 2.1.0版 2019-06-19 15:24:24 +08:00
陈精华
37762cf034 支持FTP文件地址作为预览源url 2019-06-19 15:24:24 +08:00
陈精华
a78f1e5f8e Docker构建 2019-06-19 15:24:24 +08:00
陈精华
440b8030e0 新增Docker构建 2019-06-19 15:24:24 +08:00
陈精华
fb7cdfbef7 支持http/https文件流作为预览源url 2019-06-19 15:24:24 +08:00
陈精华
cf1ee9c631 支持自动清理预览文件及缓存 2019-06-19 15:24:24 +08:00
陈精华
13123f8f9d addTask转码优化 2019-06-19 15:24:24 +08:00
陈精华
189bc3965d 2.1.0迭代 2019-06-19 15:24:24 +08:00
kl
0aa7444dba Update pom.xml 2019-05-30 09:08:08 +08:00
32 changed files with 420 additions and 112 deletions

4
.gitignore vendored
View File

@@ -37,4 +37,6 @@ nbdist/
/producer/tmp /producer/tmp
/.temfile /.temfile
.temfile .temfile
convertedFile/ convertedFile/
jodconverter-web/src/main/cache/
jodconverter-web/src/main/file/

31
Dockerfile Normal file
View File

@@ -0,0 +1,31 @@
FROM centos:centos7.6.1810
MAINTAINER chenjh "842761733@qq.com"
ADD jodconverter-web/target/kkFileView-*.tar.gz /opt/
COPY fonts/* /usr/share/fonts/
RUN yum install -y kde-l10n-Chinese &&\
yum install -y glibc-common &&\
yum install -y fontconfig &&\
yum install -y mkfontscale &&\
localedef -c -f UTF-8 -i zh_CN zh_CN.utf8 &&\
export LANG=zh_CN.UTF-8 &&\
echo "export LANG=zh_CN.UTF-8" >> /etc/locale.conf &&\
LANG="zh_CN.UTF-8" &&\
yum install -y java-1.8.0-openjdk.x86_64 &&\
yum install -y wget &&\
yum install -y libXext.x86_64 &&\
yum groupinstall -y "X Window System" &&\
cd /tmp &&\
wget https://iweb.dl.sourceforge.net/project/openofficeorg.mirror/4.1.6/binaries/zh-CN/Apache_OpenOffice_4.1.6_Linux_x86-64_install-rpm_zh-CN.tar.gz -cO openoffice_rpm.tar.gz &&\
tar zxf /tmp/openoffice_rpm.tar.gz &&\
cd /tmp/zh-CN/RPMS &&\
rpm -Uvih *.rpm &&\
rpm -Uvih desktop-integration/openoffice4.1.6-redhat-menus-4.1.6-9790.noarch.rpm &&\
rm -f /tmp/openoffice_rpm.tar.gz &&\
rm -rf /tmp/zh-CN &&\
cd /usr/share/fonts &&\
mkfontscale &&\
mkfontdir &&\
fc-cache -fv
ENV LC_ALL zh_CN.UTF-8
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-2.1.0/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-2.1.0/conf/application.properties","-jar","/opt/kkFileView-2.1.0/bin/kkFileView-2.1.0.jar"]

View File

@@ -58,26 +58,22 @@ Considering space issues, the pictures of other types of documents will not be s
- Jodconverter - Jodconverter
> Dependencies > Dependencies
- Redis(Optional, Unnecessary by default) - Redis(Optional, Unnecessary by default)
- OpenOffice or LibreOffice - OpenOffice or LibreOffice(Integrated on Windows, will be installed automatically on Linux, need to be manually installed on Mac OS)
1. First step`git pull https://github.com/kekingcn/file-online-preview.git` 1. First step`git pull https://github.com/kekingcn/file-online-preview.git`
2. Second stepconfigure redis address and OpenOffice directorysuch as 2. Third stepRun the main method of FilePreviewApplication.java.After starting,visit `http://localhost:8012/`.
```
##The folder for files which are uploaded to the server(Because of running as jar)
file.dir = C:\\Users\\yudian\\Desktop\\dev\\
## openoffice configuration
office.home = C:\\Program Files (x86)\\OpenOffice 4
```
'file.dir' is the real storage address of the converted files, please end with '/'.
3. Third stepRun the main method of FilePreviewApplication.java.After starting,visit `http://localhost:8012/`.
If everything is ok,you will see the picture below. If everything is ok,you will see the picture below.
![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png") ![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png")
### Changelog ### Changelog
> June 18th 2019
1. Support automatic cleaning of cache and preview files
2. Support http/https stream url file preview
3. Support FTP url file preview
4. Add Docker build
> April 8th 2019 > April 8th 2019
1. Cache and queue implementations abstract, providing JDK and REDIS implementations (REDIS becomes optional dependencies) 1. Cache and queue implementations abstract, providing JDK and REDIS implementations (REDIS becomes optional dependencies)
2. Provides zip and tar.gz packages, and provides a one-click startup script 2. Provides zip and tar.gz packages, and provides a one-click startup script

View File

@@ -52,26 +52,22 @@ QQ群号613025121
- jodconverter - jodconverter
> 依赖外部环境 > 依赖外部环境
- redis (可选,默认不用) - redis (可选,默认不用)
- OpenOffice或者LibreOffice - OpenOffice或者LibreOffice(Windows下已内置Linux会自动安装Mac OS下需要手动安装)
1. 第一步pull项目https://github.com/kekingcn/file-online-preview.git 1. 第一步pull项目https://github.com/kekingcn/file-online-preview.git
2. 第二步:配置OpenOffice目录 3. 第二步:运行FilePreviewApplication的main方法服务启动后访问http://localhost:8012/
```
##资源映射路径(因为jar方式运行的原因)
file.dir = C:\\Users\\yudian\\Desktop\\dev\\
## openoffice相关配置
office.home = C:\\Program Files (x86)\\OpenOffice 4
```
file.dir为转换文件实际存储地址注意要以/结尾
3. 第三步运行FilePreviewApplication的main方法服务启动后访问http://localhost:8012/
会看到如下界面,代表服务启动成功 会看到如下界面,代表服务启动成功
![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png") ![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png")
### 历史更新记录 ### 历史更新记录
> 2019年06月18日
1. 支持自动清理缓存及预览文件
2. 支持http/https下载流url文件预览
3. 支持FTP url文件预览
4. 加入Docker构建
> 2019年04月08日 > 2019年04月08日
1. 缓存及队列实现抽象提供JDK和REDIS两种实现(REDIS成为可选依赖) 1. 缓存及队列实现抽象提供JDK和REDIS两种实现(REDIS成为可选依赖)
2. 打包方式提供zip和tar.gz包并提供一键启动脚本 2. 打包方式提供zip和tar.gz包并提供一键启动脚本

0
fonts/.gitkeep Normal file
View File

View File

@@ -12,7 +12,7 @@
<groupId>cn.keking</groupId> <groupId>cn.keking</groupId>
<artifactId>kkFileView</artifactId> <artifactId>kkFileView</artifactId>
<version>2.0.2</version> <version>2.1.0</version>
<properties> <properties>
@@ -147,10 +147,16 @@
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>1.2</version> <version>1.2</version>
</dependency> </dependency>
<!-- FTP -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency> <dependency>
<groupId>com.thoughtworks.xstream</groupId> <groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId> <artifactId>xstream</artifactId>
<version>1.3.1</version> <version>1.4.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>

View File

@@ -4,4 +4,4 @@ cd "%KKFILEVIEW_BIN_FOLDER%"
echo Using KKFILEVIEW_BIN_FOLDER %KKFILEVIEW_BIN_FOLDER% echo Using KKFILEVIEW_BIN_FOLDER %KKFILEVIEW_BIN_FOLDER%
echo Starting kkFileView... echo Starting kkFileView...
echo Please check log file for more information echo Please check log file for more information
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\conf\application.properties -jar kkFileView-2.0.2.jar -> ..\log\kkFileView.log java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\conf\application.properties -jar kkFileView-2.1.0.jar -> ..\log\kkFileView.log

View File

@@ -27,4 +27,4 @@ else
fi fi
echo "Starting kkFileView..." echo "Starting kkFileView..."
echo "Please check log file for more information" echo "Please check log file for more information"
nohup java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../conf/application.properties -jar kkFileView-2.0.2.jar > ../log/kkFileView.log 2>&1 & nohup java -Dfile.encoding=UTF-8 -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../conf/application.properties -jar kkFileView-2.1.0.jar > ../log/kkFileView.log 2>&1 &

View File

@@ -27,6 +27,8 @@ spring.http.multipart.max-file-size=100MB
#redis连接 #redis连接
#spring.redisson.address = 192.168.1.204:6379 #spring.redisson.address = 192.168.1.204:6379
#spring.redisson.password = xxx #spring.redisson.password = xxx
#缓存自动清理(每晚3点自动清理) true 为开启,注释掉或其他值都为关闭
cache.clean = true
#######################################可在运行时动态配置####################################### #######################################可在运行时动态配置#######################################
#文本类型,默认如下,可自定义添加 #文本类型,默认如下,可自定义添加
@@ -37,3 +39,10 @@ spring.http.multipart.max-file-size=100MB
#converted.file.charset = GBK #converted.file.charset = GBK
#office类型文档(word ppt)样式,默认为图片(image)可配置为pdf预览时也有按钮切换 #office类型文档(word ppt)样式,默认为图片(image)可配置为pdf预览时也有按钮切换
#office.preview.type = pdf #office.preview.type = pdf
#预览源为FTP时 FTP用户名可在ftp url后面加参数ftp.username=ftpuser指定不指定默认用配置的
ftp.username = ftpuser
#预览源为FTP时 FTP密码可在ftp url后面加参数ftp.password=123456指定不指定默认用配置的
ftp.password = 123456
#预览源为FTP时, FTP连接默认ControlEncoding(根据FTP服务器操作系统选择Linux一般为UTF-8Windows一般为GBK)可在ftp url后面加参数ftp.control.encoding=UTF-8指定不指定默认用配置的
ftp.control.encoding = UTF-8

View File

@@ -18,6 +18,9 @@ public class ConfigConstants {
private static String[] media = {}; private static String[] media = {};
private static String convertedFileCharset; private static String convertedFileCharset;
private static String officePreviewType; private static String officePreviewType;
private static String ftpUsername;
private static String ftpPassword;
private static String ftpControlEncoding;
private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator; private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator;
public static String[] getSimText() { public static String[] getSimText() {
@@ -52,6 +55,30 @@ public class ConfigConstants {
ConfigConstants.officePreviewType = officePreviewType; ConfigConstants.officePreviewType = officePreviewType;
} }
public static String getFtpUsername() {
return ftpUsername;
}
public static void setFtpUsername(String ftpUsername) {
ConfigConstants.ftpUsername = ftpUsername;
}
public static String getFtpPassword() {
return ftpPassword;
}
public static String getFtpControlEncoding() {
return ftpControlEncoding;
}
public static void setFtpControlEncoding(String ftpControlEncoding) {
ConfigConstants.ftpControlEncoding = ftpControlEncoding;
}
public static void setFtpPassword(String ftpPassword) {
ConfigConstants.ftpPassword = ftpPassword;
}
public static String getFileDir() { public static String getFileDir() {
return fileDir; return fileDir;
} }

View File

@@ -24,6 +24,10 @@ public class ConfigRefreshComponent {
public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql"; public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql";
public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv"; public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv";
public static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding");
public static final String DEFAULT_FTP_USERNAME = null;
public static final String DEFAULT_FTP_PASSWORD = null;
public static final String DEFAULT_FTP_CONTROL_ENCODING = "UTF-8";
@PostConstruct @PostConstruct
@@ -37,13 +41,15 @@ public class ConfigRefreshComponent {
public void run() { public void run() {
try { try {
Properties properties = new Properties(); Properties properties = new Properties();
Properties sysProperties = System.getProperties();
String text; String text;
String media; String media;
String convertedFileCharset = sysProperties.getProperty("sun.jnu.encoding");
String[] textArray; String[] textArray;
String[] mediaArray; String[] mediaArray;
String convertedFileCharset;
String officePreviewType; String officePreviewType;
String ftpUsername;
String ftpPassword;
String ftpControlEncoding;
String configFilePath = OfficeUtils.getCustomizedConfigPath(); String configFilePath = OfficeUtils.getCustomizedConfigPath();
while (true) { while (true) {
FileReader fileReader = new FileReader(configFilePath); FileReader fileReader = new FileReader(configFilePath);
@@ -51,20 +57,26 @@ public class ConfigRefreshComponent {
properties.load(bufferedReader); properties.load(bufferedReader);
text = properties.getProperty("simText", DEFAULT_TXT_TYPE); text = properties.getProperty("simText", DEFAULT_TXT_TYPE);
media = properties.getProperty("media", DEFAULT_MEDIA_TYPE); media = properties.getProperty("media", DEFAULT_MEDIA_TYPE);
convertedFileCharset = properties.getProperty("converted.file.charset", convertedFileCharset); convertedFileCharset = properties.getProperty("converted.file.charset", DEFAULT_CONVERTER_CHARSET);
officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE); officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE);
ftpUsername = properties.getProperty("ftp.username", DEFAULT_FTP_USERNAME);
ftpPassword = properties.getProperty("ftp.password", DEFAULT_FTP_PASSWORD);
ftpControlEncoding = properties.getProperty("ftp.control.encoding", DEFAULT_FTP_CONTROL_ENCODING);
textArray = text.split(","); textArray = text.split(",");
mediaArray = media.split(","); mediaArray = media.split(",");
ConfigConstants.setSimText(textArray); ConfigConstants.setSimText(textArray);
ConfigConstants.setMedia(mediaArray); ConfigConstants.setMedia(mediaArray);
ConfigConstants.setConvertedFileCharset(convertedFileCharset); ConfigConstants.setConvertedFileCharset(convertedFileCharset);
ConfigConstants.setOfficePreviewType(officePreviewType); ConfigConstants.setOfficePreviewType(officePreviewType);
ConfigConstants.setFtpUsername(ftpUsername);
ConfigConstants.setFtpPassword(ftpPassword);
ConfigConstants.setFtpControlEncoding(ftpControlEncoding);
bufferedReader.close(); bufferedReader.close();
fileReader.close(); fileReader.close();
Thread.sleep(1000L); Thread.sleep(1000L);
} }
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
LOGGER.error("读取配置文件异常{}", e); LOGGER.error("读取配置文件异常", e);
} }
} }
} }

View File

@@ -35,7 +35,7 @@ public class FileConverQueueTask {
@PostConstruct @PostConstruct
public void startTask(){ public void startTask(){
ExecutorService executorService = Executors.newFixedThreadPool(3); ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new ConverTask(previewFactory,cacheService,fileUtils)); executorService.submit(new ConverTask(previewFactory, cacheService, fileUtils));
logger.info("队列处理文件转换任务启动完成 "); logger.info("队列处理文件转换任务启动完成 ");
} }
@@ -47,7 +47,7 @@ public class FileConverQueueTask {
FileUtils fileUtils; FileUtils fileUtils;
public ConverTask(FilePreviewFactory previewFactory, CacheService cacheService,FileUtils fileUtils) { public ConverTask(FilePreviewFactory previewFactory, CacheService cacheService, FileUtils fileUtils) {
this.previewFactory = previewFactory; this.previewFactory = previewFactory;
this.cacheService = cacheService; this.cacheService = cacheService;
this.fileUtils=fileUtils; this.fileUtils=fileUtils;
@@ -58,13 +58,13 @@ public class FileConverQueueTask {
while (true) { while (true) {
try { try {
String url = cacheService.takeQueueTask(); String url = cacheService.takeQueueTask();
if(url!=null){ if(url != null){
FileAttribute fileAttribute=fileUtils.getFileAttribute(url); FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
logger.info("正在处理转换任务,文件名称【{}】",fileAttribute.getName()); logger.info("正在处理转换任务,文件名称【{}】",fileAttribute.getName());
FileType fileType=fileAttribute.getType(); FileType fileType=fileAttribute.getType();
if(fileType.equals(FileType.compress) || fileType.equals(FileType.office)){ if(fileType.equals(FileType.compress) || fileType.equals(FileType.office)){
FilePreview filePreview=previewFactory.get(url); FilePreview filePreview=previewFactory.get(fileAttribute);
filePreview.filePreviewHandle(url,new ExtendedModelMap()); filePreview.filePreviewHandle(url, new ExtendedModelMap(), fileAttribute);
} }
} }
} catch (Exception e) { } catch (Exception e) {

View File

@@ -1,5 +1,6 @@
package cn.keking.service; package cn.keking.service;
import cn.keking.model.FileAttribute;
import org.springframework.ui.Model; import org.springframework.ui.Model;
/** /**
@@ -7,5 +8,5 @@ import org.springframework.ui.Model;
* Content : * Content :
*/ */
public interface FilePreview { public interface FilePreview {
String filePreviewHandle(String url, Model model); String filePreviewHandle(String url, Model model, FileAttribute fileAttribute);
} }

View File

@@ -5,7 +5,6 @@ import cn.keking.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import java.util.Map; import java.util.Map;
@@ -22,9 +21,8 @@ public class FilePreviewFactory {
@Autowired @Autowired
ApplicationContext context; ApplicationContext context;
public FilePreview get(String url) { public FilePreview get(FileAttribute fileAttribute) {
Map<String, FilePreview> filePreviewMap = context.getBeansOfType(FilePreview.class); Map<String, FilePreview> filePreviewMap = context.getBeansOfType(FilePreview.class);
FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
return filePreviewMap.get(fileAttribute.getType().getInstanceName()); return filePreviewMap.get(fileAttribute.getType().getInstanceName());
} }
} }

View File

@@ -20,7 +20,7 @@ public interface CacheService {
void initPDFCachePool(Integer capacity); void initPDFCachePool(Integer capacity);
void initIMGCachePool(Integer capacity); void initIMGCachePool(Integer capacity);
public void initPdfImagesCachePool(Integer capacity); void initPdfImagesCachePool(Integer capacity);
void putPDFCache(String key, String value); void putPDFCache(String key, String value);
void putImgCache(String key, List<String> value); void putImgCache(String key, List<String> value);
Map<String, String> getPDFCache(); Map<String, String> getPDFCache();
@@ -30,7 +30,11 @@ public interface CacheService {
Integer getPdfImageCache(String key); Integer getPdfImageCache(String key);
void putPdfImageCache(String pdfFilePath, int num); void putPdfImageCache(String pdfFilePath, int num);
void cleanCache();
void addQueueTask(String url); void addQueueTask(String url);
String takeQueueTask() throws InterruptedException; String takeQueueTask() throws InterruptedException;
} }

View File

@@ -116,6 +116,13 @@ public class CacheServiceJDKImpl implements CacheService {
pdfImagesCache.put(pdfFilePath, num); pdfImagesCache.put(pdfFilePath, num);
} }
@Override
public void cleanCache() {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
initIMGCachePool(CacheService.DEFAULT_IMG_CAPACITY);
initPdfImagesCachePool(CacheService.DEFAULT_PDFIMG_CAPACITY);
}
@Override @Override
public void addQueueTask(String url) { public void addQueueTask(String url) {
blockingQueue.add(url); blockingQueue.add(url);

View File

@@ -94,6 +94,13 @@ public class CacheServiceRedisImpl implements CacheService {
convertedList.fastPut(pdfFilePath, num); convertedList.fastPut(pdfFilePath, num);
} }
@Override
public void cleanCache() {
cleanPdfCache();
cleanImgCache();
cleanPdfImgCache();
}
@Override @Override
public void addQueueTask(String url) { public void addQueueTask(String url) {
RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName); RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
@@ -105,4 +112,19 @@ public class CacheServiceRedisImpl implements CacheService {
RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName); RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
return queue.take(); return queue.take();
} }
private void cleanPdfCache() {
RMapCache<String, String> pdfCache = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
pdfCache.clear();
}
private void cleanImgCache() {
RMapCache<String, List<String>> imgCache = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
imgCache.clear();
}
private void cleanPdfImgCache() {
RMapCache<String, Integer> pdfImg = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_IMGS_KEY);
pdfImg.clear();
}
} }

View File

@@ -179,6 +179,17 @@ public class CacheServiceRocksDBImpl implements CacheService {
} }
} }
@Override
public void cleanCache() {
try {
cleanPdfCache();
cleanImgCache();
cleanPdfImgCache();
} catch (IOException | RocksDBException e) {
LOGGER.error("Clean Cache Exception" + e);
}
}
@Override @Override
public void addQueueTask(String url) { public void addQueueTask(String url) {
blockingQueue.add(url); blockingQueue.add(url);
@@ -210,4 +221,19 @@ public class CacheServiceRocksDBImpl implements CacheService {
bis.close(); bis.close();
return obj; return obj;
} }
private void cleanPdfCache() throws IOException, RocksDBException {
Map<String, String> initPDFCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(initPDFCache));
}
private void cleanImgCache() throws IOException, RocksDBException {
Map<String, List<String>> initIMGCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes(), toByteArray(initIMGCache));
}
private void cleanPdfImgCache() throws IOException, RocksDBException {
Map<String, Integer> initPDFIMGCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes(), toByteArray(initPDFIMGCache));
}
} }

View File

@@ -28,15 +28,13 @@ public class CompressFilePreviewImpl implements FilePreview{
ZipReader zipReader; ZipReader zipReader;
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String decodedUrl=fileAttribute.getDecodedUrl();
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileTree = null; String fileTree = null;
// 判断文件名是否存在(redis缓存读取) // 判断文件名是否存在(redis缓存读取)
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) { if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName); ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix); model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());

View File

@@ -19,9 +19,8 @@ public class MediaFilePreviewImpl implements FilePreview {
FileUtils fileUtils; FileUtils fileUtils;
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
model.addAttribute("mediaUrl", url); model.addAttribute("mediaUrl", url);
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
if ("flv".equalsIgnoreCase(suffix)) { if ("flv".equalsIgnoreCase(suffix)) {
return "flv"; return "flv";

View File

@@ -9,9 +9,7 @@ import cn.keking.utils.FileUtils;
import cn.keking.utils.OfficeToPdf; import cn.keking.utils.OfficeToPdf;
import cn.keking.utils.PdfUtils; import cn.keking.utils.PdfUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -44,14 +42,12 @@ public class OfficeFilePreviewImpl implements FilePreview {
public static final String OFFICE_PREVIEW_TYPE_ALLIMAGES = "allImages"; public static final String OFFICE_PREVIEW_TYPE_ALLIMAGES = "allImages";
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
// 预览Type参数传了就取参数的没传取系统默认 // 预览Type参数传了就取参数的没传取系统默认
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString(); String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
String originUrl = model.asMap().get("originUrl").toString(); String originUrl = (String) model.asMap().get("originUrl");
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String decodedUrl=fileAttribute.getDecodedUrl();
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx"); boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf"); String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
String outFilePath = fileDir + pdfName; String outFilePath = fileDir + pdfName;
@@ -59,7 +55,7 @@ public class OfficeFilePreviewImpl implements FilePreview {
if (!fileUtils.listConvertedFiles().containsKey(pdfName)) { if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
String filePath = fileDir + fileName; String filePath = fileDir + fileName;
if (!new File(filePath).exists()) { if (!new File(filePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null); ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, null);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix); model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());
@@ -81,7 +77,7 @@ public class OfficeFilePreviewImpl implements FilePreview {
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath)); fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
} }
} }
if (!isHtml && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType))) { if (!isHtml && originUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType))) {
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl); List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl);
if (imageUrls == null || imageUrls.size() < 1) { if (imageUrls == null || imageUrls.size() < 1) {
model.addAttribute("msg", "office转图片异常请联系管理员"); model.addAttribute("msg", "office转图片异常请联系管理员");

View File

@@ -17,9 +17,7 @@ public class OtherFilePreviewImpl implements FilePreview {
FileUtils fileUtils; FileUtils fileUtils;
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
model.addAttribute("fileType",fileAttribute.getSuffix()); model.addAttribute("fileType",fileAttribute.getSuffix());
model.addAttribute("msg", "系统还不支持该格式文件的在线预览," + model.addAttribute("msg", "系统还不支持该格式文件的在线预览," +
"如有需要请按下方显示的邮箱地址联系系统维护人员"); "如有需要请按下方显示的邮箱地址联系系统维护人员");

View File

@@ -34,9 +34,7 @@ public class PdfFilePreviewImpl implements FilePreview{
String fileDir = ConfigConstants.getFileDir(); String fileDir = ConfigConstants.getFileDir();
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String decodedUrl=fileAttribute.getDecodedUrl();
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString(); String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
@@ -47,7 +45,7 @@ public class PdfFilePreviewImpl implements FilePreview{
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) { if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) {
//当文件不存在时,就去下载 //当文件不存在时,就去下载
if (!new File(outFilePath).exists()) { if (!new File(outFilePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName); ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix); model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());

View File

@@ -1,5 +1,6 @@
package cn.keking.service.impl; package cn.keking.service.impl;
import cn.keking.model.FileAttribute;
import cn.keking.service.FilePreview; import cn.keking.service.FilePreview;
import cn.keking.utils.FileUtils; import cn.keking.utils.FileUtils;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -21,7 +22,7 @@ public class PictureFilePreviewImpl implements FilePreview {
FileUtils fileUtils; FileUtils fileUtils;
@Override @Override
public String filePreviewHandle(String url, Model model) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileKey=(String) RequestContextHolder.currentRequestAttributes().getAttribute("fileKey",0); String fileKey=(String) RequestContextHolder.currentRequestAttributes().getAttribute("fileKey",0);
List imgUrls = Lists.newArrayList(url); List imgUrls = Lists.newArrayList(url);
try{ try{

View File

@@ -23,8 +23,7 @@ public class SimTextFilePreviewImpl implements FilePreview{
FileUtils fileUtils; FileUtils fileUtils;
@Override @Override
public String filePreviewHandle(String url, Model model){ public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute){
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String decodedUrl=fileAttribute.getDecodedUrl(); String decodedUrl=fileAttribute.getDecodedUrl();
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
ReturnResponse<String> response = simTextUtil.readSimText(decodedUrl, fileName); ReturnResponse<String> response = simTextUtil.readSimText(decodedUrl, fileName);

View File

@@ -1,8 +1,14 @@
package cn.keking.utils; package cn.keking.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
public class DeleteFileUtil { public class DeleteFileUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(DeleteFileUtil.class);
/** /**
* 删除单个文件 * 删除单个文件
* *
@@ -15,14 +21,14 @@ public class DeleteFileUtil {
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) { if (file.exists() && file.isFile()) {
if (file.delete()) { if (file.delete()) {
System.out.println("删除单个文件" + fileName + "成功!"); LOGGER.info("删除单个文件" + fileName + "成功!");
return true; return true;
} else { } else {
System.out.println("删除单个文件" + fileName + "失败!"); LOGGER.info("删除单个文件" + fileName + "失败!");
return false; return false;
} }
} else { } else {
System.out.println("删除单个文件失败:" + fileName + "不存在!"); LOGGER.info("删除单个文件失败:" + fileName + "不存在!");
return false; return false;
} }
} }
@@ -43,7 +49,7 @@ public class DeleteFileUtil {
File dirFile = new File(dir); File dirFile = new File(dir);
// 如果dir对应的文件不存在或者不是一个目录则退出 // 如果dir对应的文件不存在或者不是一个目录则退出
if ((!dirFile.exists()) || (!dirFile.isDirectory())) { if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
System.out.println("删除目录失败:" + dir + "不存在!"); LOGGER.info("删除目录失败:" + dir + "不存在!");
return false; return false;
} }
boolean flag = true; boolean flag = true;
@@ -65,7 +71,7 @@ public class DeleteFileUtil {
} }
} }
if (!flag) { if (!flag) {
System.out.println("删除目录失败!"); LOGGER.info("删除目录失败!");
return false; return false;
} }
return true; return true;

View File

@@ -1,7 +1,11 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
@@ -13,7 +17,16 @@ import java.util.UUID;
@Component @Component
public class DownloadUtils { public class DownloadUtils {
String fileDir = ConfigConstants.getFileDir(); private static final Logger LOGGER = LoggerFactory.getLogger(DownloadUtils.class);
private String fileDir = ConfigConstants.getFileDir();
@Autowired
private FileUtils fileUtils;
private static final String URL_PARAM_FTP_USERNAME = "ftp.username";
private static final String URL_PARAM_FTP_PASSWORD = "ftp.password";
private static final String URL_PARAM_FTP_CONTROL_ENCODING = "ftp.control.encoding";
/** /**
* 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解 * 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解
@@ -21,11 +34,12 @@ public class DownloadUtils {
* 应该是转义出了问题url转义中会把+号当成空格来计算所以才会出现这种情况遂想要通过整体替换空格为加号因为url * 应该是转义出了问题url转义中会把+号当成空格来计算所以才会出现这种情况遂想要通过整体替换空格为加号因为url
* 中的参数部分是不会出现空格的但是文件名中就不好确定了所以只对url参数部分做替换 * 中的参数部分是不会出现空格的但是文件名中就不好确定了所以只对url参数部分做替换
* 注: 针对URLEncoder.encode(s,charset)会将空格转成+的情况需要做下面的替换工作 * 注: 针对URLEncoder.encode(s,charset)会将空格转成+的情况需要做下面的替换工作
* @param urlAddress * @param fileAttribute
* @param type
* @return * @return
*/ */
public ReturnResponse<String> downLoad(String urlAddress, String type, String fileName){ public ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
String urlAddress = fileAttribute.getDecodedUrl();
String type = fileAttribute.getSuffix();
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", ""); ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
URL url = null; URL url = null;
try { try {
@@ -40,7 +54,7 @@ public class DownloadUtils {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
if (null == fileName) { if (null == fileName) {
fileName = uuid+ "."+type; fileName = uuid+ "."+type;
}else { // 文件后缀不一致时以type为准(针对simText【将类txt文件转为txt】) } else { // 文件后缀不一致时以type为准(针对simText【将类txt文件转为txt】)
fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type); fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type);
} }
String realPath = fileDir + fileName; String realPath = fileDir + fileName;
@@ -49,17 +63,24 @@ public class DownloadUtils {
dirFile.mkdirs(); dirFile.mkdirs();
} }
try { try {
URLConnection connection = url.openConnection(); if ("ftp".equals(url.getProtocol())) {
InputStream in = connection.getInputStream(); String ftpUsername = fileUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
String ftpPassword = fileUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);
String ftpControlEncoding = fileUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING);
FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding);
} else {
URLConnection connection = url.openConnection();
InputStream in = connection.getInputStream();
FileOutputStream os = new FileOutputStream(realPath); FileOutputStream os = new FileOutputStream(realPath);
byte[] buffer = new byte[4 * 1024]; byte[] buffer = new byte[4 * 1024];
int read; int read;
while ((read = in.read(buffer)) > 0) { while ((read = in.read(buffer)) > 0) {
os.write(buffer, 0, read); os.write(buffer, 0, read);
}
os.close();
in.close();
} }
os.close();
in.close();
response.setContent(realPath); response.setContent(realPath);
// 同样针对类txt文件如果成功msg包含的是转换后的文件名 // 同样针对类txt文件如果成功msg包含的是转换后的文件名
response.setMsg(fileName); response.setMsg(fileName);
@@ -68,15 +89,14 @@ public class DownloadUtils {
if("txt".equals(type)){ if("txt".equals(type)){
convertTextPlainFileCharsetToUtf8(realPath); convertTextPlainFileCharsetToUtf8(realPath);
} }
return response; return response;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("文件下载失败", e);
response.setCode(1); response.setCode(1);
response.setContent(null); response.setContent(null);
if (e instanceof FileNotFoundException) { if (e instanceof FileNotFoundException) {
response.setMsg("文件不存在!!!"); response.setMsg("文件不存在!!!");
}else { } else {
response.setMsg(e.getMessage()); response.setMsg(e.getMessage());
} }
return response; return response;

View File

@@ -9,11 +9,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.*; import java.io.*;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -63,13 +65,17 @@ public class FileUtils {
* @return * @return
*/ */
public FileType typeFromUrl(String url) { public FileType typeFromUrl(String url) {
String[] simText = ConfigConstants.getSimText();
String[] media = ConfigConstants.getMedia();
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length()); String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length());
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
return typeFromFileName(fileName);
}
private FileType typeFromFileName(String fileName) {
String[] simText = ConfigConstants.getSimText();
String[] media = ConfigConstants.getMedia();
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
if (listPictureTypes().contains(fileType.toLowerCase())) { if (listPictureTypes().contains(fileType.toLowerCase())) {
return FileType.picture; return FileType.picture;
} }
if (listArchiveTypes().contains(fileType.toLowerCase())) { if (listArchiveTypes().contains(fileType.toLowerCase())) {
return FileType.compress; return FileType.compress;
@@ -265,22 +271,83 @@ public class FileUtils {
private String suffixFromUrl(String url) { private String suffixFromUrl(String url) {
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length()); String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length());
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
return suffixFromFileName(fileName);
}
private String suffixFromFileName(String fileName) {
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
return fileType; return fileType;
} }
/**
* 获取url中的参数
* @param url
* @param name
* @return
*/
public String getUrlParameterReg(String url, String name) {
Map<String, String> mapRequest = new HashMap();
String strUrlParam = truncateUrlPage(url);
if (strUrlParam == null) {
return "";
}
//每个键值为一组
String[] arrSplit=strUrlParam.split("[&]");
for(String strSplit:arrSplit) {
String[] arrSplitEqual= strSplit.split("[=]");
//解析出键值
if(arrSplitEqual.length > 1) {
//正确解析
mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
} else if (!arrSplitEqual[0].equals("")) {
//只有参数没有值,不加入
mapRequest.put(arrSplitEqual[0], "");
}
}
return mapRequest.get(name);
}
/**
* 去掉url中的路径留下请求参数部分
* @param strURL url地址
* @return url请求参数部分
*/
private String truncateUrlPage(String strURL) {
String strAllParam = null;
strURL = strURL.trim();
String[] arrSplit = strURL.split("[?]");
if(strURL.length() > 1) {
if(arrSplit.length > 1) {
if(arrSplit[1] != null) {
strAllParam=arrSplit[1];
}
}
}
return strAllParam;
}
public FileAttribute getFileAttribute(String url) { public FileAttribute getFileAttribute(String url) {
String decodedUrl=null; String decodedUrl = null;
try { try {
decodedUrl = URLDecoder.decode(url, "utf-8"); decodedUrl = URLDecoder.decode(url, "utf-8");
}catch (UnsupportedEncodingException e){ } catch (UnsupportedEncodingException e){
log.debug("url解码失败"); log.error("url解码失败");
}
String fileName;
FileType type;
String suffix;
String fullFileName = getUrlParameterReg(decodedUrl, "fullfilename");
if (!StringUtils.isEmpty(fullFileName)) {
fileName = fullFileName;
type = typeFromFileName(fileName);
suffix = suffixFromFileName(fileName);
} else {
fileName = getFileNameFromURL(decodedUrl);
type = typeFromUrl(url);
suffix = suffixFromUrl(url);
} }
// 路径转码
FileType type = typeFromUrl(url);
String suffix = suffixFromUrl(url);
// 抽取文件并返回文件列表
String fileName = getFileNameFromURL(decodedUrl);
return new FileAttribute(type,suffix,fileName,url,decodedUrl); return new FileAttribute(type,suffix,fileName,url,decodedUrl);
} }
} }

View File

@@ -0,0 +1,57 @@
package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
/**
* @auther: chenjh
* @since: 2019/6/18 14:36
*/
public class FtpUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(FtpUtils.class);
public static FTPClient connect(String host, int port, String username, String password, String controlEncoding) throws IOException {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(host, port);
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
ftpClient.login(username, password);
}
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
}
ftpClient.setControlEncoding(controlEncoding);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
return ftpClient;
}
public static void download(String ftpUrl, String localFilePath, String ftpUsername, String ftpPassword, String ftpControlEncoding) throws IOException {
String username = StringUtils.isEmpty(ftpUsername) ? ConfigConstants.getFtpUsername() : ftpUsername;
String password = StringUtils.isEmpty(ftpPassword) ? ConfigConstants.getFtpPassword() : ftpPassword;
String controlEncoding = StringUtils.isEmpty(ftpControlEncoding) ? ConfigConstants.getFtpControlEncoding() : ftpControlEncoding;
URL url = new URL(ftpUrl);
String host = url.getHost();
int port = (url.getPort() == -1) ? url.getDefaultPort() : url.getPort();
String remoteFilePath = url.getPath();
LOGGER.debug("FTP connection url:{}, username:{}, password:{}, controlEncoding:{}, localFilePath:{}", ftpUrl, username, password, controlEncoding, localFilePath);
FTPClient ftpClient = connect(host, port, username, password, controlEncoding);
OutputStream outputStream = new FileOutputStream(localFilePath);
ftpClient.enterLocalPassiveMode();
boolean downloadResult = ftpClient.retrieveFile(new String(remoteFilePath.getBytes(controlEncoding), "ISO-8859-1"), outputStream);
LOGGER.debug("FTP download result {}", downloadResult);
outputStream.flush();
outputStream.close();
ftpClient.logout();
ftpClient.disconnect();
}
}

View File

@@ -1,15 +1,34 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.service.cache.CacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/**
* @auther: chenjh
* @since: 2019/6/11 7:45
*/
@Component @Component
@ConditionalOnExpression("'${cache.clean:false}'.equals('true')")
public class ShedulerClean { public class ShedulerClean {
String fileDir = ConfigConstants.getFileDir();
// @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次 private static final Logger LOGGER = LoggerFactory.getLogger(ShedulerClean.class);
public void clean(){
System.out.println("执行一次清空文件夹"); @Autowired
private CacheService cacheService;
private String fileDir = ConfigConstants.getFileDir();
@Scheduled(cron = "0 0 3 * * ?") //每晚3点执行一次
public void clean() {
LOGGER.info("Cache clean start");
cacheService.cleanCache();
DeleteFileUtil.deleteDirectory(fileDir); DeleteFileUtil.deleteDirectory(fileDir);
LOGGER.info("Cache clean end");
} }
} }

View File

@@ -1,6 +1,7 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -12,12 +13,14 @@ import org.springframework.stereotype.Component;
*/ */
@Component @Component
public class SimTextUtil { public class SimTextUtil {
String fileDir = ConfigConstants.getFileDir();
@Autowired @Autowired
DownloadUtils downloadUtils; private FileUtils fileUtils;
@Autowired
private DownloadUtils downloadUtils;
public ReturnResponse<String> readSimText(String url, String fileName){ public ReturnResponse<String> readSimText(String url, String fileName){
ReturnResponse<String> response = downloadUtils.downLoad(url, "txt", fileName); FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
return response; return response;
} }
} }

View File

@@ -1,10 +1,14 @@
package cn.keking.web.controller; package cn.keking.web.controller;
import cn.keking.model.FileAttribute;
import cn.keking.service.FilePreview; import cn.keking.service.FilePreview;
import cn.keking.service.FilePreviewFactory; import cn.keking.service.FilePreviewFactory;
import cn.keking.service.cache.CacheService; import cn.keking.service.cache.CacheService;
import cn.keking.utils.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@@ -26,12 +30,17 @@ import java.util.List;
@Controller @Controller
public class OnlinePreviewController { public class OnlinePreviewController {
private static final Logger LOGGER = LoggerFactory.getLogger(OnlinePreviewController.class);
@Autowired @Autowired
FilePreviewFactory previewFactory; FilePreviewFactory previewFactory;
@Autowired @Autowired
CacheService cacheService; CacheService cacheService;
@Autowired
private FileUtils fileUtils;
/** /**
* @param url * @param url
* @param model * @param model
@@ -39,11 +48,12 @@ public class OnlinePreviewController {
*/ */
@RequestMapping(value = "onlinePreview", method = RequestMethod.GET) @RequestMapping(value = "onlinePreview", method = RequestMethod.GET)
public String onlinePreview(String url, Model model, HttpServletRequest req) { public String onlinePreview(String url, Model model, HttpServletRequest req) {
FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
req.setAttribute("fileKey", req.getParameter("fileKey")); req.setAttribute("fileKey", req.getParameter("fileKey"));
model.addAttribute("officePreviewType", req.getParameter("officePreviewType")); model.addAttribute("officePreviewType", req.getParameter("officePreviewType"));
model.addAttribute("originUrl",req.getRequestURL().toString()); model.addAttribute("originUrl", req.getRequestURL().toString());
FilePreview filePreview = previewFactory.get(url); FilePreview filePreview = previewFactory.get(fileAttribute);
return filePreview.filePreviewHandle(url, model); return filePreview.filePreviewHandle(url, model, fileAttribute);
} }
/** /**
@@ -105,7 +115,7 @@ public class OnlinePreviewController {
resp.getOutputStream().write(bs, 0, len); resp.getOutputStream().write(bs, 0, len);
} }
} catch (IOException | URISyntaxException e) { } catch (IOException | URISyntaxException e) {
e.printStackTrace(); LOGGER.error("下载pdf文件失败", e);
} finally { } finally {
if (inputStream != null) { if (inputStream != null) {
IOUtils.closeQuietly(inputStream); IOUtils.closeQuietly(inputStream);