Compare commits
1 Commits
dependabot
...
index-ui
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e8bf0d359 |
@ -28,5 +28,5 @@ ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
|
||||
ENV PATH $PATH:$JAVA_HOME/bin
|
||||
ENV LANG zh_CN.UTF-8
|
||||
ENV LC_ALL zh_CN.UTF-8
|
||||
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-3.5/bin
|
||||
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-3.5/config/application.properties","-jar","/opt/kkFileView-3.5/bin/kkFileView-3.5.jar"]
|
||||
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-3.3.0/bin
|
||||
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-3.3.0/config/application.properties","-jar","/opt/kkFileView-3.3.0/bin/kkFileView-3.3.0.jar"]
|
||||
56
README.md
56
README.md
@ -2,14 +2,14 @@
|
||||
此项目为文件文档在线预览项目解决方案,对标业内付费产品有【[永中office](http://dcs.yozosoft.com/)】【[office365](http://www.officeweb365.com/)】【[idocv](https://www.idocv.com/)】等,在取得公司高层同意后以Apache协议开源出来反哺社区,在此特别感谢@唐老大的支持以及@端木详笑的贡献。该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,Excel,pdf,txt,zip,rar,图片等等
|
||||
### 项目特性
|
||||
|
||||
1. 支持 office, pdf, cad 等办公文档
|
||||
1. 支持 txt, xml(渲染), md(渲染), java, php, py, js, css 等所有纯文本
|
||||
1. 支持 zip, rar, jar, tar, gzip 等压缩包
|
||||
1. 支持 jpg, jpeg, png, gif, tif, tiff 等图片预览(翻转,缩放,镜像)
|
||||
1. 使用 spring-boot 开发,预览服务搭建部署非常简便
|
||||
1. rest 接口提供服务,跨语言、跨平台特性(java,php,python,go,php,....)都支持,应用接入简单方便
|
||||
1. 支持office,pdf, cad等办公文档
|
||||
1. 支持txt,java,php,py,md,js,css等所有纯文本
|
||||
1. 支持zip,rar,jar,tar,gzip等压缩包
|
||||
1. 支持jpg,jpeg,png,gif等图片预览(翻转,缩放,镜像)
|
||||
1. 使用spring boot开发,预览服务搭建部署非常简便
|
||||
1. rest接口提供服务,跨平台特性(java,php,python,go,php,....)都支持,应用接入简单方便
|
||||
1. 抽象预览服务接口,方便二次开发,非常方便添加其他类型文件预览支持
|
||||
1. 最最重要 Apache 协议开源,代码 pull 下来想干嘛就干嘛
|
||||
1. 最最重要Apache协议开源,代码pull下来想干嘛就干嘛
|
||||
|
||||
### 官网及文档
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
1. English document:https://gitee.com/kekingcn/file-online-preview/blob/master/README.en.md
|
||||
|
||||
### 联系我们,加入组织
|
||||
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少 Google 或 baidu 过,珍爱生命远离无效的交流沟通
|
||||
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少Google或baidu过,珍爱生命远离无效的交流沟通
|
||||
|
||||

|
||||
|
||||
@ -99,40 +99,16 @@ pdf预览模式预览效果如下
|
||||
- jodconverter
|
||||
> 依赖外部环境
|
||||
- redis (可选,默认不用)
|
||||
- OpenOffice 或者 LibreOffice( Windows 下已内置,Linux 脚本启动模式会自动安装,Mac OS 下需要手动安装)
|
||||
- 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
|
||||
|
||||
3. 第二步:运行 ServerMain 的 main 方法,服务启动后,访问 http://localhost:8012/
|
||||
3. 第二步:运行FilePreviewApplication的main方法,服务启动后,访问http://localhost:8012/
|
||||
会看到如下界面,代表服务启动成功
|
||||
|
||||

|
||||
|
||||
### 历史更新记录
|
||||
|
||||
> 2021年1月28日 :
|
||||
|
||||
2020农历年最后一个版本发布,主要包含了部分 UI 改进,和解决了 QQ 群友、 Issue 里反馈的 Bug 修复,最最重要的是发个新版,过个好年
|
||||
|
||||
1. 引入galimatias,解决不规范文件名导致文件下载异常
|
||||
2. 更新index接入演示界面UI风格
|
||||
3. 更新markdown文件预览UI风格
|
||||
4. 更新XML文件预览UI风格,调整类文本预览架构,更方便扩展
|
||||
5. 更新simTxT文件预览UI风格
|
||||
6. 调整多图连续预览上下翻图的UI
|
||||
7. 采用apache-common-io包简化所有的文件下载io操作
|
||||
8. XML文件预览支持切换纯文本模式
|
||||
9. 增强url base64解码失败时的提示信息
|
||||
10. 修复导包错误以及图片预览 bug
|
||||
11. 修复发行包运行时找不到日志目录的问题
|
||||
12. 修复压缩包内多图连续预览的bug
|
||||
13. 修复大小写文件类型后缀没通用匹配的问题
|
||||
14. 指定Base64转码采用Apache Commons-code中的实现,修复base64部分jdk版本下出现的异常
|
||||
15. 修复类文本类型HTML文件预览的bug
|
||||
16. 修复:dwg文件预览时无法在jpg和pdf两种类型之间切换
|
||||
17. escaping of dangerous characters to prevent reflected xss
|
||||
18. 修复重复编码导致文档转图片预览失败的问题&编码规范
|
||||
|
||||
> 2020年12月27日 :
|
||||
|
||||
2020年年终大版本更新,架构全面设计,代码全面重构,代码质量全面提升,二次开发更便捷,欢迎拉源码品鉴,提issue、pr共同建设
|
||||
@ -207,13 +183,5 @@ pdf预览模式预览效果如下
|
||||
1. 引入pdf.js预览doc等文件,支持doc标题生成pdf预览菜单,支持手机端预览
|
||||
|
||||
### 使用登记
|
||||
如果这个项目解决了你的实际问题,可在 https://gitee.com/kekingcn/file-online-preview/issues/IGSBV
|
||||
如果这个项目解决了你的实际问题,可在https://gitee.com/kekingcn/file-online-preview/issues/IGSBV
|
||||
登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢
|
||||
|
||||
### Stars 趋势图
|
||||
#### Gitee
|
||||
[](https://whnb.wang/kekingcn/file-online-preview?e=86400)
|
||||
|
||||
#### GitHub
|
||||
|
||||
[](https://starchart.cc/kekingcn/kkFileView)
|
||||
|
||||
@ -3,15 +3,13 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<groupId>cn.keking</groupId>
|
||||
<version>3.5</version>
|
||||
</parent>
|
||||
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>office-plugin</artifactId>
|
||||
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- required for org.hyperic:sigar -->
|
||||
|
||||
@ -81,7 +81,7 @@ public class OfficeUtils {
|
||||
}
|
||||
if (PlatformUtils.isWindows()) {
|
||||
// %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones
|
||||
String officePluginPath = ConfigUtils.getOfficePluginPath();
|
||||
String homePath = ConfigUtils.getHomePath();
|
||||
String programFiles = System.getenv("ProgramFiles(x86)");
|
||||
if (programFiles == null) {
|
||||
programFiles = System.getenv("ProgramFiles");
|
||||
@ -89,7 +89,7 @@ public class OfficeUtils {
|
||||
return findOfficeHome(
|
||||
programFiles + File.separator + "OpenOffice 4",
|
||||
programFiles + File.separator + "LibreOffice 4",
|
||||
officePluginPath + File.separator + "windows-office"
|
||||
homePath + File.separator + "office"
|
||||
);
|
||||
} else if (PlatformUtils.isMac()) {
|
||||
return findOfficeHome(
|
||||
|
||||
@ -9,7 +9,6 @@ import java.io.File;
|
||||
public class ConfigUtils {
|
||||
|
||||
private static final String MAIN_DIRECTORY_NAME = "server";
|
||||
private static final String OFFICE_PLUGIN_NAME = "office-plugin";
|
||||
|
||||
public static String getHomePath() {
|
||||
String userDir = System.getenv("KKFILEVIEW_BIN_FOLDER");
|
||||
@ -29,23 +28,6 @@ public class ConfigUtils {
|
||||
return userDir;
|
||||
}
|
||||
|
||||
|
||||
public static String getOfficePluginPath() {
|
||||
String userDir = System.getenv("KKFILEVIEW_BIN_FOLDER");
|
||||
if (userDir == null) {
|
||||
userDir = System.getProperty("user.dir");
|
||||
}
|
||||
if (userDir.endsWith("bin")) {
|
||||
userDir = userDir.substring(0, userDir.length() - 4);
|
||||
} else {
|
||||
String separator = File.separator;
|
||||
if (!userDir.contains(OFFICE_PLUGIN_NAME)) {
|
||||
userDir = userDir + separator + OFFICE_PLUGIN_NAME;
|
||||
}
|
||||
}
|
||||
return userDir;
|
||||
}
|
||||
|
||||
public static String getCustomizedConfigPath() {
|
||||
String homePath = getHomePath();
|
||||
String separator = java.io.File.separator;
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
======================================================================
|
||||
OpenOffice 4.1.6 ReadMe
|
||||
======================================================================
|
||||
Windows 内置集成的的 OpenOffice
|
||||
68
pom.xml
68
pom.xml
@ -2,60 +2,36 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<version>3.5</version>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring.boot.version>2.4.2</spring.boot.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<version>3.3.0</version>
|
||||
<modules>
|
||||
<module>office-plugin</module>
|
||||
<module>server</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<properties>
|
||||
<build.exclude.resource></build.exclude.resource>
|
||||
</properties>
|
||||
<activation>
|
||||
<!--默认激活开发环境-->
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<properties>
|
||||
<build.exclude.resource>*.properties</build.exclude.resource>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<name>file-online-preview</name>
|
||||
<description>专注文件在线预览服务</description>
|
||||
<url>https://github.com/kekingcn/kkFileView</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/kekingcn/kkFileView</url>
|
||||
<connection>scm:git:git://github.com/kekingcn/kkFileView.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/kekingcn/kkFileView.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>klboke</id>
|
||||
<name>kl</name>
|
||||
<email>g632104866@gmail.com</email>
|
||||
<url>http://www.kailing.pub</url>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>gitchenjh</id>
|
||||
<name>chenjinghua</name>
|
||||
<email>842761733@qq.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<issueManagement>
|
||||
<system>github</system>
|
||||
<url>https://github.com/kekingcn/kkFileView/issues</url>
|
||||
</issueManagement>
|
||||
|
||||
</project>
|
||||
|
||||
@ -2,27 +2,31 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<groupId>cn.keking</groupId>
|
||||
<version>3.5</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.8.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>kkFileView</artifactId>
|
||||
<version>3.3.0</version>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- required for org.hyperic:sigar -->
|
||||
<id>jboss-public-repository-group</id>
|
||||
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -51,7 +55,13 @@
|
||||
<dependency>
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>office-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>commons-io</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
@ -67,7 +77,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.17</version>
|
||||
<version>3.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
@ -95,6 +105,11 @@
|
||||
<artifactId>fr.opensagres.xdocreport.document</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<!-- 解压(apache) -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
@ -149,7 +164,7 @@
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.16</version>
|
||||
<version>1.4.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
|
||||
@ -193,7 +208,6 @@
|
||||
<version>0.2.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
@ -205,6 +219,9 @@
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/config</directory>
|
||||
<excludes>
|
||||
<exclude>${build.exclude.resource}</exclude>
|
||||
</excludes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
@ -212,25 +229,16 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<configuration>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/dist-win32.xml</descriptor>
|
||||
<descriptor>src/main/assembly/dist-linux.xml</descriptor>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
|
||||
@ -35,10 +35,10 @@
|
||||
<outputDirectory>${file.separator}log</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../office-plugin/windows-office</directory>
|
||||
<outputDirectory>${file.separator}windows-office</outputDirectory>
|
||||
<directory>src/main/office</directory>
|
||||
<outputDirectory>${file.separator}office</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<outputDirectory>${file.separator}bin</outputDirectory>
|
||||
<includes>
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
||||
<id>make-assembly</id>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>true</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/bin</directory>
|
||||
<outputDirectory>${file.separator}bin</outputDirectory>
|
||||
<includes>
|
||||
<include>*.sh</include>
|
||||
</includes>
|
||||
<fileMode>755</fileMode>
|
||||
<lineEnding>unix</lineEnding>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src/main/config</directory>
|
||||
<outputDirectory>${file.separator}config</outputDirectory>
|
||||
<lineEnding>unix</lineEnding>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src/main/log</directory>
|
||||
<outputDirectory>${file.separator}log</outputDirectory>
|
||||
<lineEnding>unix</lineEnding>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<outputDirectory>${file.separator}bin</outputDirectory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
||||
<id>make-assembly</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>true</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/bin</directory>
|
||||
<outputDirectory>${file.separator}bin</outputDirectory>
|
||||
<includes>
|
||||
<include>*.bat</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src/main/config</directory>
|
||||
<outputDirectory>${file.separator}config</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src/main/log</directory>
|
||||
<outputDirectory>${file.separator}log</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../office-plugin/windows-office</directory>
|
||||
<outputDirectory>${file.separator}windows-office</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<outputDirectory>${file.separator}bin</outputDirectory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@ -6,4 +6,4 @@ echo Starting kkFileView...
|
||||
echo Please check log file in ../log/kkFileView.log for more information
|
||||
echo You can get help in our official homesite: https://kkFileView.keking.cn
|
||||
echo If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers
|
||||
java -Dspring.config.location=..\config\application.properties -jar kkFileView-3.5.jar -> ..\log\kkFileView.log
|
||||
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\config\application.properties -jar kkFileView-3.3.0.jar -> ..\log\kkFileView.log
|
||||
@ -29,4 +29,4 @@ echo "Starting kkFileView..."
|
||||
echo "Please execute ./showlog.sh to check log for more information"
|
||||
echo "You can get help in our official homesite: https://kkFileView.keking.cn"
|
||||
echo "If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers"
|
||||
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar kkFileView-3.5.jar > ../log/kkFileView.log 2>&1 &
|
||||
nohup java -Dfile.encoding=UTF-8 -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../config/application.properties -jar kkFileView-3.3.0.jar > ../log/kkFileView.log 2>&1 &
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
#######################################不可动态配置,需要重启生效#######################################
|
||||
server.port = ${KK_SERVER_PORT:8012}
|
||||
server.servlet.context-path= ${KK_CONTEXT_PATH:/}
|
||||
server.servlet.encoding.charset = utf-8
|
||||
#文件上传限制
|
||||
spring.servlet.multipart.max-file-size=500MB
|
||||
spring.servlet.multipart.max-request-size=500MB
|
||||
server.context-path = ${KK_CONTEXT_PATH:/}
|
||||
spring.http.encoding.charset = utf8
|
||||
## Freemarker 配置
|
||||
spring.freemarker.template-loader-path = classpath:/web/
|
||||
spring.freemarker.cache = false
|
||||
@ -16,11 +13,10 @@ spring.freemarker.expose-session-attributes = true
|
||||
spring.freemarker.request-context-attribute = request
|
||||
spring.freemarker.suffix = .ftl
|
||||
|
||||
# office-plugin
|
||||
## office转换服务的进程数,默认开启两个进程
|
||||
office.plugin.server.ports = 2001,2002
|
||||
## office 转换服务 task 超时时间,默认五分钟
|
||||
office.plugin.task.timeout = 5m
|
||||
server.tomcat.uri-encoding = UTF-8
|
||||
#文件上传限制
|
||||
spring.http.multipart.max-request-size=500MB
|
||||
spring.http.multipart.max-file-size=500MB
|
||||
|
||||
#文件资源路径(默认为打包根路径下的file目录下)
|
||||
#file.dir = D:\\kkFileview\\
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
[#ftl]
|
||||
[#-- @implicitly included --]
|
||||
[#-- @ftlvariable name="currentUrl" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="file" type="cn.keking.model.FileAttribute" --]
|
||||
[#-- @ftlvariable name="fileName" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="fileTree" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="baseUrl" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="imgUrls" type="String" --]
|
||||
|
||||
@ -1,33 +1,22 @@
|
||||
package cn.keking;
|
||||
|
||||
import cn.keking.config.AppBanner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@ComponentScan(value = "cn.keking.*")
|
||||
public class ServerMain {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServerMain.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
ConfigurableApplicationContext context = new SpringApplicationBuilder(ServerMain.class)
|
||||
.logStartupInfo(false)
|
||||
.banner(new AppBanner())
|
||||
.run(args);
|
||||
stopWatch.stop();
|
||||
Integer port = context.getBean(ServerProperties.class).getPort();
|
||||
logger.info("kkFileView 服务启动完成,耗时:{}s,演示页请访问: http://127.0.0.1:{} ", stopWatch.getTotalTimeSeconds(), port);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
ServerMain.staticInitSystemProperty();
|
||||
SpringApplication.run(ServerMain.class, args);
|
||||
}
|
||||
|
||||
private static void staticInitSystemProperty(){
|
||||
//pdfbox兼容低版本jdk
|
||||
System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
package cn.keking.config;
|
||||
|
||||
import org.springframework.boot.Banner;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* @author kl (http://kailing.pub)
|
||||
* @since 2021/2/8
|
||||
*/
|
||||
public class AppBanner implements Banner {
|
||||
@Override
|
||||
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
|
||||
out.println(
|
||||
" _ _ ______ _ _ __ __ _ \n" +
|
||||
" | | | | | ____| (_) | | \\ \\ / / (_) \n" +
|
||||
" | | __ | | __ | |__ _ | | ___ \\ \\ / / _ ___ __ __\n" +
|
||||
" | |/ / | |/ / | __| | | | | / _ \\ \\ \\/ / | | / _ \\ \\ \\ /\\ / /\n" +
|
||||
" | < | < | | | | | | | __/ \\ / | | | __/ \\ V V / \n" +
|
||||
" |_|\\_\\ |_|\\_\\ |_| |_| |_| \\___| \\/ |_| \\___| \\_/\\_/ \n" +
|
||||
" \n" +
|
||||
" => Spring Boot :: (v2.4.2) QQ1 :: 613025121\n" +
|
||||
" => kkFileView :: (v3.5) QQ2 :: 484680571\n" +
|
||||
" => github :: https://github.com/kekingcn/kkFileView\n" +
|
||||
" => gitee :: https://gitee.com/kekingcn/file-online-preview\n");
|
||||
}
|
||||
}
|
||||
@ -16,23 +16,18 @@ import java.util.Set;
|
||||
@Component
|
||||
public class ConfigConstants {
|
||||
|
||||
static {
|
||||
//pdfbox兼容低版本jdk
|
||||
System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider");
|
||||
}
|
||||
|
||||
private static Boolean cacheEnabled;
|
||||
private static String[] simTexts = {};
|
||||
private static String[] medias = {};
|
||||
private static String officePreviewType;
|
||||
private static String officePreviewSwitchDisabled;
|
||||
private static String ftpUsername;
|
||||
private static String ftpPassword;
|
||||
private static String ftpControlEncoding;
|
||||
private static String baseUrl;
|
||||
private static String fileDir = ConfigUtils.getHomePath() + File.separator + "file" + File.separator;
|
||||
private static CopyOnWriteArraySet<String> trustHostSet;
|
||||
private static String pdfDownloadDisable;
|
||||
private static Boolean CACHE_ENABLED;
|
||||
private static String[] SIM_TEXT = {};
|
||||
private static String[] MEDIA = {};
|
||||
private static String OFFICE_PREVIEW_TYPE;
|
||||
private static String OFFICE_PREVIEW_SWITCH_DISABLED;
|
||||
private static String FTP_USERNAME;
|
||||
private static String FTP_PASSWORD;
|
||||
private static String FTP_CONTROL_ENCODING;
|
||||
private static String BASE_URL;
|
||||
private static String FILE_DIR = ConfigUtils.getHomePath() + File.separator + "file" + File.separator;
|
||||
private static CopyOnWriteArraySet<String> TRUST_HOST_SET;
|
||||
private static String PDF_DOWNLOAD_DISABLE;
|
||||
|
||||
public static final String DEFAULT_CACHE_ENABLED = "true";
|
||||
public static final String DEFAULT_TXT_TYPE = "txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
|
||||
@ -47,9 +42,8 @@ public class ConfigConstants {
|
||||
public static final String DEFAULT_TRUST_HOST = "default";
|
||||
public static final String DEFAULT_PDF_DOWNLOAD_DISABLE = "true";
|
||||
|
||||
|
||||
public static Boolean isCacheEnabled() {
|
||||
return cacheEnabled;
|
||||
return CACHE_ENABLED;
|
||||
}
|
||||
|
||||
@Value("${cache.enabled:true}")
|
||||
@ -58,11 +52,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setCacheEnabledValueValue(Boolean cacheEnabled) {
|
||||
ConfigConstants.cacheEnabled = cacheEnabled;
|
||||
CACHE_ENABLED = cacheEnabled;
|
||||
}
|
||||
|
||||
public static String[] getSimText() {
|
||||
return simTexts;
|
||||
return SIM_TEXT;
|
||||
}
|
||||
|
||||
@Value("${simText:txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd}")
|
||||
@ -72,11 +66,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setSimTextValue(String[] simText) {
|
||||
ConfigConstants.simTexts = simText;
|
||||
SIM_TEXT = simText;
|
||||
}
|
||||
|
||||
public static String[] getMedia() {
|
||||
return medias;
|
||||
return MEDIA;
|
||||
}
|
||||
|
||||
@Value("${media:mp3,wav,mp4,flv}")
|
||||
@ -86,11 +80,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setMediaValue(String[] Media) {
|
||||
ConfigConstants.medias = Media;
|
||||
MEDIA = Media;
|
||||
}
|
||||
|
||||
public static String getOfficePreviewType() {
|
||||
return officePreviewType;
|
||||
return OFFICE_PREVIEW_TYPE;
|
||||
}
|
||||
|
||||
@Value("${office.preview.type:image}")
|
||||
@ -99,11 +93,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setOfficePreviewTypeValue(String officePreviewType) {
|
||||
ConfigConstants.officePreviewType = officePreviewType;
|
||||
OFFICE_PREVIEW_TYPE = officePreviewType;
|
||||
}
|
||||
|
||||
public static String getFtpUsername() {
|
||||
return ftpUsername;
|
||||
return FTP_USERNAME;
|
||||
}
|
||||
|
||||
@Value("${ftp.username:}")
|
||||
@ -112,11 +106,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setFtpUsernameValue(String ftpUsername) {
|
||||
ConfigConstants.ftpUsername = ftpUsername;
|
||||
FTP_USERNAME = ftpUsername;
|
||||
}
|
||||
|
||||
public static String getFtpPassword() {
|
||||
return ftpPassword;
|
||||
return FTP_PASSWORD;
|
||||
}
|
||||
|
||||
@Value("${ftp.password:}")
|
||||
@ -125,11 +119,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setFtpPasswordValue(String ftpPassword) {
|
||||
ConfigConstants.ftpPassword = ftpPassword;
|
||||
FTP_PASSWORD = ftpPassword;
|
||||
}
|
||||
|
||||
public static String getFtpControlEncoding() {
|
||||
return ftpControlEncoding;
|
||||
return FTP_CONTROL_ENCODING;
|
||||
}
|
||||
|
||||
@Value("${ftp.control.encoding:UTF-8}")
|
||||
@ -138,11 +132,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setFtpControlEncodingValue(String ftpControlEncoding) {
|
||||
ConfigConstants.ftpControlEncoding = ftpControlEncoding;
|
||||
FTP_CONTROL_ENCODING = ftpControlEncoding;
|
||||
}
|
||||
|
||||
public static String getBaseUrl() {
|
||||
return baseUrl;
|
||||
return BASE_URL;
|
||||
}
|
||||
|
||||
@Value("${base.url:default}")
|
||||
@ -151,11 +145,11 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static void setBaseUrlValue(String baseUrl) {
|
||||
ConfigConstants.baseUrl = baseUrl;
|
||||
BASE_URL = baseUrl;
|
||||
}
|
||||
|
||||
public static String getFileDir() {
|
||||
return fileDir;
|
||||
return FILE_DIR;
|
||||
}
|
||||
|
||||
@Value("${file.dir:default}")
|
||||
@ -168,7 +162,7 @@ public class ConfigConstants {
|
||||
if (!fileDir.endsWith(File.separator)) {
|
||||
fileDir = fileDir + File.separator;
|
||||
}
|
||||
ConfigConstants.fileDir = fileDir;
|
||||
FILE_DIR = fileDir;
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,15 +184,15 @@ public class ConfigConstants {
|
||||
}
|
||||
|
||||
public static Set<String> getTrustHostSet() {
|
||||
return trustHostSet;
|
||||
return TRUST_HOST_SET;
|
||||
}
|
||||
|
||||
private static void setTrustHostSet(CopyOnWriteArraySet<String> trustHostSet) {
|
||||
ConfigConstants.trustHostSet = trustHostSet;
|
||||
ConfigConstants.TRUST_HOST_SET = trustHostSet;
|
||||
}
|
||||
|
||||
public static String getPdfDownloadDisable() {
|
||||
return pdfDownloadDisable;
|
||||
return PDF_DOWNLOAD_DISABLE;
|
||||
}
|
||||
|
||||
|
||||
@ -207,18 +201,17 @@ public class ConfigConstants {
|
||||
setPdfDownloadDisableValue(pdfDownloadDisable);
|
||||
}
|
||||
public static void setPdfDownloadDisableValue(String pdfDownloadDisable) {
|
||||
ConfigConstants.pdfDownloadDisable = pdfDownloadDisable;
|
||||
PDF_DOWNLOAD_DISABLE = pdfDownloadDisable;
|
||||
}
|
||||
|
||||
public static String getOfficePreviewSwitchDisabled() {
|
||||
return officePreviewSwitchDisabled;
|
||||
return OFFICE_PREVIEW_SWITCH_DISABLED;
|
||||
}
|
||||
@Value("${office.preview.switch.disabled:true}")
|
||||
public void setOfficePreviewSwitchDisabled(String officePreviewSwitchDisabled) {
|
||||
ConfigConstants.officePreviewSwitchDisabled = officePreviewSwitchDisabled;
|
||||
OFFICE_PREVIEW_SWITCH_DISABLED = officePreviewSwitchDisabled;
|
||||
}
|
||||
public static void setOfficePreviewSwitchDisabledValue(String officePreviewSwitchDisabled) {
|
||||
ConfigConstants.officePreviewSwitchDisabled = officePreviewSwitchDisabled;
|
||||
OFFICE_PREVIEW_SWITCH_DISABLED = officePreviewSwitchDisabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
19
server/src/main/java/cn/keking/config/RFCConfig.java
Normal file
19
server/src/main/java/cn/keking/config/RFCConfig.java
Normal file
@ -0,0 +1,19 @@
|
||||
package cn.keking.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author chenjh
|
||||
* @since 2020/5/18 13:41
|
||||
*/
|
||||
@Configuration
|
||||
public class RFCConfig {
|
||||
|
||||
@Bean
|
||||
public Boolean setRequestTargetAllow() {
|
||||
// RFC 7230,RFC 3986规范不允许url相关特殊字符,手动指定Tomcat url允许特殊符号, 如{}做入参,其他符号按需添加。见tomcat的HttpParser源码。
|
||||
System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow", "|{}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
package cn.keking.config;
|
||||
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
@ -31,7 +31,7 @@ public class SchedulerCleanConfig {
|
||||
public void clean() {
|
||||
logger.info("Cache clean start");
|
||||
cacheService.cleanCache();
|
||||
KkFileUtils.deleteDirectory(fileDir);
|
||||
FileUtils.deleteDirectory(fileDir);
|
||||
logger.info("Cache clean end");
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,14 +4,14 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* @author: chenjh
|
||||
* @since: 2019/4/16 20:04
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
public class WebConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(WebConfig.class);
|
||||
/**
|
||||
@ -22,5 +22,6 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
String filePath = ConfigConstants.getFileDir();
|
||||
LOGGER.info("Add resource locations: {}", filePath);
|
||||
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/","file:" + filePath);
|
||||
super.addResourceHandlers(registry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,63 +11,52 @@ import java.util.Map;
|
||||
*/
|
||||
public enum FileType {
|
||||
|
||||
PICTURE("pictureFilePreviewImpl"),
|
||||
COMPRESS("compressFilePreviewImpl"),
|
||||
OFFICE("officeFilePreviewImpl"),
|
||||
SIMTEXT("simTextFilePreviewImpl"),
|
||||
PDF("pdfFilePreviewImpl"),
|
||||
CODE("codeFilePreviewImpl"),
|
||||
OTHER("otherFilePreviewImpl"),
|
||||
MEDIA("mediaFilePreviewImpl"),
|
||||
MARKDOWN("markdownFilePreviewImpl"),
|
||||
XML("xmlFilePreviewImpl"),
|
||||
FLV("flvFilePreviewImpl"),
|
||||
CAD("cadFilePreviewImpl"),
|
||||
TIFF("tiffFilePreviewImpl");
|
||||
picture("pictureFilePreviewImpl"),
|
||||
compress("compressFilePreviewImpl"),
|
||||
office("officeFilePreviewImpl"),
|
||||
simText("simTextFilePreviewImpl"),
|
||||
pdf("pdfFilePreviewImpl"),
|
||||
other("otherFilePreviewImpl"),
|
||||
media("mediaFilePreviewImpl"),
|
||||
markdown("markdownFilePreviewImpl"),
|
||||
xml("xmlFilePreviewImpl"),
|
||||
flv("flvFilePreviewImpl"),
|
||||
cad("cadFilePreviewImpl");
|
||||
|
||||
|
||||
private static final String[] OFFICE_TYPES = {"docx", "wps", "doc", "xls", "xlsx", "ppt", "pptx"};
|
||||
private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "raw"};
|
||||
private static final String[] OFFICE_TYPES = {"docx", "doc", "xls", "xlsx", "ppt", "pptx"};
|
||||
private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "RAW"};
|
||||
private static final String[] ARCHIVE_TYPES = {"rar", "zip", "jar", "7-zip", "tar", "gzip", "7z"};
|
||||
private static final String[] TIFF_TYPES = {"tif", "tiff"};
|
||||
private static final String[] SSIM_TEXT_TYPES = ConfigConstants.getSimText();
|
||||
private static final String[] CODES = {"java", "c", "php", "go", "python", "py", "js", "html", "ftl", "css", "lua", "sh", "rb", "yml", "json", "h", "cpp", "cs", "aspx", "jsp"};
|
||||
private static final String[] MEDIA_TYPES = ConfigConstants.getMedia();
|
||||
private static final Map<String, FileType> FILE_TYPE_MAPPER = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (String office : OFFICE_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(office, FileType.OFFICE);
|
||||
FILE_TYPE_MAPPER.put(office, FileType.office);
|
||||
}
|
||||
for (String picture : PICTURE_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(picture, FileType.PICTURE);
|
||||
FILE_TYPE_MAPPER.put(picture, FileType.picture);
|
||||
}
|
||||
for (String archive : ARCHIVE_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(archive, FileType.COMPRESS);
|
||||
FILE_TYPE_MAPPER.put(archive, FileType.compress);
|
||||
}
|
||||
for (String text : SSIM_TEXT_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(text, FileType.SIMTEXT);
|
||||
FILE_TYPE_MAPPER.put(text, FileType.simText);
|
||||
}
|
||||
for (String media : MEDIA_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(media, FileType.MEDIA);
|
||||
FILE_TYPE_MAPPER.put(media, FileType.media);
|
||||
}
|
||||
for (String tif : TIFF_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(tif, FileType.TIFF);
|
||||
}
|
||||
for (String code : CODES) {
|
||||
FILE_TYPE_MAPPER.put(code, FileType.CODE);
|
||||
}
|
||||
FILE_TYPE_MAPPER.put("md", FileType.MARKDOWN);
|
||||
FILE_TYPE_MAPPER.put("xml", FileType.XML);
|
||||
FILE_TYPE_MAPPER.put("pdf", FileType.PDF);
|
||||
FILE_TYPE_MAPPER.put("dwg", FileType.CAD);
|
||||
FILE_TYPE_MAPPER.put("flv", FileType.FLV);
|
||||
FILE_TYPE_MAPPER.put("md", FileType.markdown);
|
||||
FILE_TYPE_MAPPER.put("xml", FileType.xml);
|
||||
FILE_TYPE_MAPPER.put("pdf", FileType.pdf);
|
||||
FILE_TYPE_MAPPER.put("dwg", FileType.cad);
|
||||
FILE_TYPE_MAPPER.put("flv", FileType.flv);
|
||||
|
||||
}
|
||||
|
||||
private static FileType to(String fileType) {
|
||||
return FILE_TYPE_MAPPER.getOrDefault(fileType, OTHER);
|
||||
private static FileType to(String fileType){
|
||||
return FILE_TYPE_MAPPER.getOrDefault(fileType,other);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型)
|
||||
*
|
||||
@ -82,8 +71,7 @@ public enum FileType {
|
||||
|
||||
public static FileType typeFromFileName(String fileName) {
|
||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
String lowerCaseFileType = fileType.toLowerCase();
|
||||
return FileType.to(lowerCaseFileType);
|
||||
return FileType.to(fileType);
|
||||
}
|
||||
|
||||
private final String instanceName;
|
||||
|
||||
@ -2,7 +2,7 @@ package cn.keking.service;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@ -48,7 +48,7 @@ public class CompressFileReader {
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String archiveFileName = fileHandlerService.getFileNameFromPath(filePath);
|
||||
try {
|
||||
ZipFile zipFile = new ZipFile(filePath, KkFileUtils.getFileEncode(filePath));
|
||||
ZipFile zipFile = new ZipFile(filePath, FileUtils.getFileEncode(filePath));
|
||||
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
|
||||
// 排序
|
||||
entries = sortZipEntries(entries);
|
||||
@ -68,7 +68,7 @@ public class CompressFileReader {
|
||||
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
||||
parentName = (level - 1) + "_" + parentName;
|
||||
FileType type = FileType.typeFromUrl(childName);
|
||||
if (type.equals(FileType.PICTURE)) {//添加图片文件到图片列表
|
||||
if (type.equals(FileType.picture)) {//添加图片文件到图片列表
|
||||
imgUrls.add(baseUrl + childName);
|
||||
}
|
||||
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory, fileKey);
|
||||
@ -121,7 +121,7 @@ public class CompressFileReader {
|
||||
}
|
||||
String parentName = getLast2FileName(fullName, "\\", archiveFileName);
|
||||
FileType type = FileType.typeFromUrl(childName);
|
||||
if (type.equals(FileType.PICTURE)) {//添加图片文件到图片列表
|
||||
if (type.equals(FileType.picture)) {//添加图片文件到图片列表
|
||||
imgUrls.add(baseUrl + childName);
|
||||
}
|
||||
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory, fileKey);
|
||||
@ -164,7 +164,7 @@ public class CompressFileReader {
|
||||
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
||||
parentName = (level - 1) + "_" + parentName;
|
||||
FileType type = FileType.typeFromUrl(childName);
|
||||
if (type.equals(FileType.PICTURE)) {//添加图片文件到图片列表
|
||||
if (type.equals(FileType.picture)) {//添加图片文件到图片列表
|
||||
imgUrls.add(baseUrl + childName);
|
||||
}
|
||||
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory, fileKey);
|
||||
@ -382,7 +382,7 @@ public class CompressFileReader {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
FileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
|
||||
private void extractZipFile(String childName, InputStream zipFile) {
|
||||
@ -439,7 +439,7 @@ public class CompressFileReader {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
FileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,7 +468,7 @@ public class CompressFileReader {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
FileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
|
||||
private void extractRarFile(String childName, FileHeader header, Archive archive) {
|
||||
|
||||
@ -62,7 +62,7 @@ public class FileConvertQueueTask {
|
||||
FileAttribute fileAttribute = fileHandlerService.getFileAttribute(url,null);
|
||||
FileType fileType = fileAttribute.getType();
|
||||
logger.info("正在处理预览转换任务,url:{},预览类型:{}", url, fileType);
|
||||
if(fileType.equals(FileType.COMPRESS) || fileType.equals(FileType.OFFICE) || fileType.equals(FileType.CAD)) {
|
||||
if(fileType.equals(FileType.compress) || fileType.equals(FileType.office) || fileType.equals(FileType.cad)) {
|
||||
FilePreview filePreview = previewFactory.get(fileAttribute);
|
||||
filePreview.filePreviewHandle(url, new ExtendedModelMap(), fileAttribute);
|
||||
} else {
|
||||
|
||||
@ -4,7 +4,7 @@ import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import com.aspose.cad.Color;
|
||||
import com.aspose.cad.fileformats.cad.CadDrawTypeMode;
|
||||
@ -178,15 +178,14 @@ public class FileHandlerService {
|
||||
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
|
||||
String urlPrefix;
|
||||
try {
|
||||
urlPrefix = baseUrl + URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20");
|
||||
urlPrefix = baseUrl + URLEncoder.encode(URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"), uriEncoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("UnsupportedEncodingException", e);
|
||||
urlPrefix = baseUrl + pdfFolder;
|
||||
}
|
||||
if (imageCount != null && imageCount > 0) {
|
||||
for (int i = 0; i < imageCount; i++) {
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
imageUrls.add(urlPrefix + "/" + i + imageFileSuffix);
|
||||
}
|
||||
return imageUrls;
|
||||
}
|
||||
try {
|
||||
@ -264,7 +263,7 @@ public class FileHandlerService {
|
||||
if (StringUtils.hasText(fullFileName)) {
|
||||
fileName = fullFileName;
|
||||
type = FileType.typeFromFileName(fullFileName);
|
||||
suffix = KkFileUtils.suffixFromFileName(fullFileName);
|
||||
suffix = FileUtils.suffixFromFileName(fullFileName);
|
||||
} else {
|
||||
fileName = WebUtils.getFileNameFromURL(url);
|
||||
type = FileType.typeFromUrl(url);
|
||||
@ -276,7 +275,7 @@ public class FileHandlerService {
|
||||
attribute.setUrl(url);
|
||||
if (req != null) {
|
||||
String officePreviewType = req.getParameter("officePreviewType");
|
||||
String fileKey = WebUtils.getUrlParameterReg(url,"fileKey");
|
||||
String fileKey = req.getParameter("fileKey");
|
||||
if (StringUtils.hasText(officePreviewType)) {
|
||||
attribute.setOfficePreviewType(officePreviewType);
|
||||
}
|
||||
|
||||
@ -14,13 +14,9 @@ public interface FilePreview {
|
||||
String COMPRESS_FILE_PREVIEW_PAGE = "compress";
|
||||
String MEDIA_FILE_PREVIEW_PAGE = "media";
|
||||
String PICTURE_FILE_PREVIEW_PAGE = "picture";
|
||||
String TIFF_FILE_PREVIEW_PAGE = "tiff";
|
||||
String OFFICE_PICTURE_FILE_PREVIEW_PAGE = "officePicture";
|
||||
String TXT_FILE_PREVIEW_PAGE = "txt";
|
||||
String CODE_FILE_PREVIEW_PAGE = "code";
|
||||
String EXEL_FILE_PREVIEW_PAGE = "html";
|
||||
String XML_FILE_PREVIEW_PAGE = "xml";
|
||||
String MARKDOWN_FILE_PREVIEW_PAGE = "markdown";
|
||||
String NOT_SUPPORTED_FILE_PAGE = "fileNotSupported";
|
||||
|
||||
String filePreviewHandle(String url, Model model, FileAttribute fileAttribute);
|
||||
|
||||
@ -8,8 +8,6 @@ import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
import org.artofsolving.jodconverter.office.OfficeUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.convert.DurationStyle;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -21,11 +19,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@ -43,12 +37,6 @@ public class OfficePluginManager {
|
||||
|
||||
private OfficeManager officeManager;
|
||||
|
||||
@Value("${office.plugin.server.ports:2001,2002}")
|
||||
private String serverPorts;
|
||||
|
||||
@Value("${office.plugin.task.timeout:5m}")
|
||||
private String timeOut;
|
||||
|
||||
@PostConstruct
|
||||
public void initOfficeManager() {
|
||||
new Thread(this::startOfficeManager).start();
|
||||
@ -69,14 +57,9 @@ public class OfficePluginManager {
|
||||
try {
|
||||
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
|
||||
configuration.setOfficeHome(officeHome);
|
||||
String []portsString = serverPorts.split(",");
|
||||
|
||||
int[] ports = Arrays.stream(portsString).mapToInt(Integer::parseInt).toArray();
|
||||
|
||||
configuration.setPortNumbers(ports);
|
||||
long timeout = DurationStyle.detectAndParse(timeOut).toMillis();
|
||||
configuration.setPortNumber(8100);
|
||||
// 设置任务执行超时为5分钟
|
||||
configuration.setTaskExecutionTimeout(timeout);
|
||||
configuration.setTaskExecutionTimeout(1000 * 60 * 5L);
|
||||
// 设置任务队列超时为24小时
|
||||
//configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);
|
||||
officeManager = configuration.buildOfficeManager();
|
||||
|
||||
@ -35,7 +35,7 @@ public class CadFilePreviewImpl implements FilePreview {
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
// 预览Type,参数传了就取参数的,没传取系统默认
|
||||
String officePreviewType = fileAttribute.getOfficePreviewType() == null ? ConfigConstants.getOfficePreviewType() : fileAttribute.getOfficePreviewType();
|
||||
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String fileName = fileAttribute.getName();
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.service.FilePreview;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
* @author kl (http://kailing.pub)
|
||||
* @since 2021/2/18
|
||||
*/
|
||||
@Component
|
||||
public class CodeFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final SimTextFilePreviewImpl filePreviewHandle;
|
||||
|
||||
public CodeFilePreviewImpl(SimTextFilePreviewImpl filePreviewHandle) {
|
||||
this.filePreviewHandle = filePreviewHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
filePreviewHandle.filePreviewHandle(url, model, fileAttribute);
|
||||
return CODE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,8 @@ import cn.keking.service.FilePreview;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
import static cn.keking.service.impl.SimTextFilePreviewImpl.TEXT_TYPE;
|
||||
|
||||
/**
|
||||
* @author kl (http://kailing.pub)
|
||||
* @since 2020/12/25
|
||||
@ -21,7 +23,7 @@ public class MarkdownFilePreviewImpl implements FilePreview {
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
simTextFilePreview.filePreviewHandle(url, model, fileAttribute);
|
||||
return MARKDOWN_FILE_PREVIEW_PAGE;
|
||||
model.addAttribute(TEXT_TYPE,"markdown");
|
||||
return simTextFilePreview.filePreviewHandle(url, model, fileAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,12 +4,10 @@ import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import jodd.io.FileUtil;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -22,6 +20,9 @@ import java.nio.charset.StandardCharsets;
|
||||
@Service
|
||||
public class SimTextFilePreviewImpl implements FilePreview {
|
||||
|
||||
public static final String TEXT_TYPE = "textType";
|
||||
public static final String DEFAULT_TEXT_TYPE = "simText";
|
||||
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public SimTextFilePreviewImpl(OtherFilePreviewImpl otherFilePreview) {
|
||||
@ -37,13 +38,14 @@ public class SimTextFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
try {
|
||||
File originFile = new File(response.getContent());
|
||||
String charset = KkFileUtils.getFileEncode(originFile);
|
||||
String fileData = FileUtil.readString(originFile, charset);
|
||||
fileData = HtmlUtils.htmlEscape(fileData, StandardCharsets.UTF_8.name());
|
||||
model.addAttribute("textData", Base64.encodeBase64String(fileData.getBytes()));
|
||||
String xmlString = FileUtils.readFileToString(originFile, StandardCharsets.UTF_8);
|
||||
model.addAttribute("textData", Base64Utils.encodeToString(xmlString.getBytes(StandardCharsets.UTF_8)));
|
||||
} catch (IOException e) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, e.getLocalizedMessage());
|
||||
}
|
||||
if (!model.containsAttribute(TEXT_TYPE)) {
|
||||
model.addAttribute(TEXT_TYPE, DEFAULT_TEXT_TYPE);
|
||||
}
|
||||
return TXT_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.service.FilePreview;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
* tiff 图片文件处理
|
||||
* @author kl (http://kailing.pub)
|
||||
* @since 2021/2/8
|
||||
*/
|
||||
@Service
|
||||
public class TiffFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final PictureFilePreviewImpl pictureFilePreview;
|
||||
|
||||
public TiffFilePreviewImpl(PictureFilePreviewImpl pictureFilePreview) {
|
||||
this.pictureFilePreview = pictureFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
pictureFilePreview.filePreviewHandle(url,model,fileAttribute);
|
||||
return TIFF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,8 @@ import cn.keking.service.FilePreview;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
import static cn.keking.service.impl.SimTextFilePreviewImpl.TEXT_TYPE;
|
||||
|
||||
/**
|
||||
* @author kl (http://kailing.pub)
|
||||
* @since 2020/12/25
|
||||
@ -20,7 +22,7 @@ public class XmlFilePreviewImpl implements FilePreview {
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
simTextFilePreview.filePreviewHandle(url, model, fileAttribute);
|
||||
return XML_FILE_PREVIEW_PAGE;
|
||||
model.addAttribute(TEXT_TYPE,"xml");
|
||||
return simTextFilePreview.filePreviewHandle(url, model, fileAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,19 +2,17 @@ package cn.keking.utils;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import io.mola.galimatias.GalimatiasParseException;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
import static cn.keking.utils.KkFileUtils.isFtpUrl;
|
||||
import static cn.keking.utils.KkFileUtils.isHttpUrl;
|
||||
|
||||
/**
|
||||
* @author yudian-it
|
||||
*/
|
||||
@ -33,26 +31,42 @@ public class DownloadUtils {
|
||||
*/
|
||||
public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
|
||||
String urlStr = fileAttribute.getUrl();
|
||||
String type = fileAttribute.getSuffix();
|
||||
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
|
||||
String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
if (null == fileName) {
|
||||
fileName = uuid + "." + type;
|
||||
} else { // 文件后缀不一致时,以type为准(针对simText【将类txt文件转为txt】)
|
||||
fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type);
|
||||
}
|
||||
String realPath = fileDir + fileName;
|
||||
File dirFile = new File(fileDir);
|
||||
if (!dirFile.exists() && !dirFile.mkdirs()) {
|
||||
logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
|
||||
}
|
||||
try {
|
||||
URL url = WebUtils.normalizedURL(urlStr);
|
||||
if (isHttpUrl(url)) {
|
||||
File realFile = new File(realPath);
|
||||
FileUtils.copyURLToFile(url,realFile);
|
||||
} else if (isFtpUrl(url)) {
|
||||
URL url = new URL(urlStr);
|
||||
if (url.getProtocol() != null && (url.getProtocol().toLowerCase().startsWith("file") || url.getProtocol().toLowerCase().startsWith("http"))) {
|
||||
byte[] bytes = getBytesFromUrl(urlStr);
|
||||
OutputStream os = new FileOutputStream(realPath);
|
||||
saveBytesToOutStream(bytes, os);
|
||||
} else if (url.getProtocol() != null && "ftp".equalsIgnoreCase(url.getProtocol())) {
|
||||
String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
|
||||
String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);
|
||||
String ftpControlEncoding = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING);
|
||||
FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding);
|
||||
} else {
|
||||
response.setCode(1);
|
||||
response.setContent(null);
|
||||
response.setMsg("url不能识别url" + urlStr);
|
||||
}
|
||||
response.setContent(realPath);
|
||||
response.setMsg(fileName);
|
||||
if (FileType.simText.equals(fileAttribute.getType())) {
|
||||
convertTextPlainFileCharsetToUtf8(realPath);
|
||||
}
|
||||
return response;
|
||||
} catch (IOException | GalimatiasParseException e) {
|
||||
} catch (IOException e) {
|
||||
logger.error("文件下载失败,url:{}", urlStr, e);
|
||||
response.setCode(1);
|
||||
response.setContent(null);
|
||||
@ -65,27 +79,82 @@ public class DownloadUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取真实文件绝对路径
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 文件路径
|
||||
*/
|
||||
private static String getRelFilePath(String fileName, FileAttribute fileAttribute) {
|
||||
String type = fileAttribute.getSuffix();
|
||||
if (null == fileName) {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
fileName = uuid + "." + type;
|
||||
} else { // 文件后缀不一致时,以type为准(针对simText【将类txt文件转为txt】)
|
||||
fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type);
|
||||
public static byte[] getBytesFromUrl(String urlStr) throws IOException {
|
||||
InputStream is = getInputStreamFromUrl(urlStr);
|
||||
if (is == null) {
|
||||
is = getInputStreamFromUrl(urlStr);
|
||||
if (is == null) {
|
||||
logger.error("文件下载异常:url:{}", urlStr);
|
||||
throw new IOException("文件下载异常:url:" + urlStr);
|
||||
}
|
||||
}
|
||||
String realPath = fileDir + fileName;
|
||||
File dirFile = new File(fileDir);
|
||||
if (!dirFile.exists() && !dirFile.mkdirs()) {
|
||||
logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
|
||||
}
|
||||
return realPath;
|
||||
return getBytesFromStream(is);
|
||||
}
|
||||
|
||||
public static void saveBytesToOutStream(byte[] b, OutputStream os) throws IOException {
|
||||
os.write(b);
|
||||
os.close();
|
||||
}
|
||||
|
||||
private static InputStream getInputStreamFromUrl(String urlStr) {
|
||||
try {
|
||||
|
||||
URL url = io.mola.galimatias.URL.parse(urlStr).toJavaURL();
|
||||
URLConnection connection = url.openConnection();
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
|
||||
}
|
||||
return connection.getInputStream();
|
||||
} catch (IOException | GalimatiasParseException e) {
|
||||
logger.warn("连接url异常:url:{}", urlStr);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getBytesFromStream(InputStream is) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, len);
|
||||
}
|
||||
byte[] b = baos.toByteArray();
|
||||
is.close();
|
||||
baos.close();
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换文本文件编码为utf8
|
||||
* 探测源文件编码,探测到编码切不为utf8则进行转码
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
*/
|
||||
private static void convertTextPlainFileCharsetToUtf8(String filePath) throws IOException {
|
||||
File sourceFile = new File(filePath);
|
||||
if (sourceFile.exists() && sourceFile.isFile() && sourceFile.canRead()) {
|
||||
String encoding = FileUtils.getFileEncode(filePath);
|
||||
if (!FileUtils.DEFAULT_FILE_ENCODING.equals(encoding)) {
|
||||
// 不为utf8,进行转码
|
||||
File tmpUtf8File = new File(filePath + ".utf8");
|
||||
Writer writer = new OutputStreamWriter(new FileOutputStream(tmpUtf8File), StandardCharsets.UTF_8);
|
||||
Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), encoding));
|
||||
char[] buf = new char[1024];
|
||||
int read;
|
||||
while ((read = reader.read(buf)) > 0) {
|
||||
writer.write(buf, 0, read);
|
||||
}
|
||||
reader.close();
|
||||
writer.close();
|
||||
// 删除源文件
|
||||
if (!sourceFile.delete()) {
|
||||
logger.error("源文件【{}】删除失败,请检查文件目录权限!", filePath);
|
||||
}
|
||||
// 重命名
|
||||
if (tmpUtf8File.renameTo(sourceFile)) {
|
||||
logger.error("临时文件【{}】重命名失败,请检查文件路径权限!", tmpUtf8File.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,39 +6,19 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Objects;
|
||||
|
||||
public class KkFileUtils {
|
||||
public class FileUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(KkFileUtils.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
|
||||
|
||||
public static final String DEFAULT_FILE_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* 判断url是否是http资源
|
||||
*
|
||||
* @param url url
|
||||
* @return 是否http
|
||||
*/
|
||||
public static boolean isHttpUrl(URL url) {
|
||||
return url.getProtocol().toLowerCase().startsWith("file") || url.getProtocol().toLowerCase().startsWith("http");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断url是否是ftp资源
|
||||
*
|
||||
* @param url url
|
||||
* @return 是否ftp
|
||||
*/
|
||||
public static boolean isFtpUrl(URL url) {
|
||||
return "ftp".equalsIgnoreCase(url.getProtocol());
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单个文件
|
||||
*
|
||||
* @param fileName 要删除的文件的文件名
|
||||
* @param fileName
|
||||
* 要删除的文件的文件名
|
||||
* @return 单个文件删除成功返回true,否则返回false
|
||||
*/
|
||||
public static boolean deleteFileByName(String fileName) {
|
||||
@ -59,26 +39,17 @@ public class KkFileUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测文件编码格式
|
||||
* 判断文件编码格式
|
||||
*
|
||||
* @param filePath 绝对路径
|
||||
* @return 编码格式
|
||||
*/
|
||||
public static String getFileEncode(String filePath) {
|
||||
return getFileEncode(new File(filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测文件编码格式
|
||||
*
|
||||
* @param file 检测的文件
|
||||
* @return 编码格式
|
||||
*/
|
||||
public static String getFileEncode(File file) {
|
||||
File file = new File(filePath);
|
||||
CharsetPrinter cp = new CharsetPrinter();
|
||||
try {
|
||||
String encoding = cp.guessEncoding(file);
|
||||
LOGGER.info("检测到文件【{}】编码: {}", file.getAbsolutePath(), encoding);
|
||||
LOGGER.info("检测到文件【{}】编码: {}", filePath, encoding);
|
||||
return encoding;
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("文件编码获取失败,采用默认的编码格式:UTF-8", e);
|
||||
@ -88,7 +59,6 @@ public class KkFileUtils {
|
||||
|
||||
/**
|
||||
* 通过文件名获取文件后缀
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @return 文件后缀
|
||||
*/
|
||||
@ -112,7 +82,8 @@ public class KkFileUtils {
|
||||
/**
|
||||
* 删除目录及目录下的文件
|
||||
*
|
||||
* @param dir 要删除的目录的文件路径
|
||||
* @param dir
|
||||
* 要删除的目录的文件路径
|
||||
* @return 目录删除成功返回true,否则返回false
|
||||
*/
|
||||
public static boolean deleteDirectory(String dir) {
|
||||
@ -132,13 +103,13 @@ public class KkFileUtils {
|
||||
for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
|
||||
// 删除子文件
|
||||
if (files[i].isFile()) {
|
||||
flag = KkFileUtils.deleteFileByName(files[i].getAbsolutePath());
|
||||
flag = FileUtils.deleteFileByName(files[i].getAbsolutePath());
|
||||
if (!flag) {
|
||||
break;
|
||||
}
|
||||
} else if (files[i].isDirectory()) {
|
||||
} else if (files[i].isDirectory()) {
|
||||
// 删除子目录
|
||||
flag = KkFileUtils.deleteDirectory(files[i].getAbsolutePath());
|
||||
flag = FileUtils.deleteDirectory(files[i].getAbsolutePath());
|
||||
if (!flag) {
|
||||
break;
|
||||
}
|
||||
@ -1,9 +1,5 @@
|
||||
package cn.keking.utils;
|
||||
|
||||
import io.mola.galimatias.GalimatiasParseException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -12,16 +8,6 @@ import java.util.Map;
|
||||
* create : 2020-12-27 1:30 上午
|
||||
**/
|
||||
public class WebUtils {
|
||||
|
||||
/**
|
||||
* 获取标准的URL
|
||||
* @param urlStr url
|
||||
* @return 标准的URL
|
||||
*/
|
||||
public static URL normalizedURL(String urlStr) throws GalimatiasParseException, MalformedURLException {
|
||||
return io.mola.galimatias.URL.parse(urlStr).toJavaURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取url中的参数
|
||||
*
|
||||
@ -95,6 +81,6 @@ public class WebUtils {
|
||||
public static String suffixFromUrl(String url) {
|
||||
String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||
return KkFileUtils.suffixFromFileName(fileName);
|
||||
return FileUtils.suffixFromFileName(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,9 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -38,10 +36,6 @@ public class FileController {
|
||||
// 获取文件名
|
||||
String fileName = file.getOriginalFilename();
|
||||
//判断是否为IE浏览器的文件名,IE浏览器下文件名会带有盘符信息
|
||||
|
||||
// escaping dangerous characters to prevent XSS
|
||||
fileName = HtmlUtils.htmlEscape(fileName, StandardCharsets.UTF_8.name());
|
||||
|
||||
// Check for Unix-style path
|
||||
int unixSep = fileName.lastIndexOf('/');
|
||||
// Check for Windows-style path
|
||||
|
||||
@ -6,16 +6,13 @@ import cn.keking.service.FilePreviewFactory;
|
||||
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.service.impl.OtherFilePreviewImpl;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import fr.opensagres.xdocreport.core.io.IOUtils;
|
||||
import io.mola.galimatias.GalimatiasParseException;
|
||||
import jodd.io.NetUtil;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -24,8 +21,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -56,13 +51,12 @@ public class OnlinePreviewController {
|
||||
public String onlinePreview(String url, Model model, HttpServletRequest req) {
|
||||
String fileUrl;
|
||||
try {
|
||||
fileUrl = new String(Base64.decodeBase64(url), StandardCharsets.UTF_8);
|
||||
fileUrl = new String(Base64Utils.decodeFromString(url));
|
||||
} 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);
|
||||
FilePreview filePreview = previewFactory.get(fileAttribute);
|
||||
logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType());
|
||||
return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
|
||||
@ -72,7 +66,7 @@ public class OnlinePreviewController {
|
||||
public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||
String fileUrls;
|
||||
try {
|
||||
fileUrls = new String(Base64.decodeBase64(urls));
|
||||
fileUrls = new String(Base64Utils.decodeFromString(urls));
|
||||
} catch (Exception ex) {
|
||||
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "urls");
|
||||
return otherFilePreview.notSupportedFile(model, errorMsg);
|
||||
@ -85,7 +79,7 @@ public class OnlinePreviewController {
|
||||
|
||||
String currentUrl = req.getParameter("currentUrl");
|
||||
if (StringUtils.hasText(currentUrl)) {
|
||||
String decodedCurrentUrl = new String(Base64.decodeBase64(currentUrl));
|
||||
String decodedCurrentUrl = new String(Base64Utils.decodeFromString(currentUrl));
|
||||
model.addAttribute("currentUrl", decodedCurrentUrl);
|
||||
} else {
|
||||
model.addAttribute("currentUrl", imgUrls.get(0));
|
||||
@ -104,10 +98,9 @@ public class OnlinePreviewController {
|
||||
public void getCorsFile(String urlPath, HttpServletResponse response) {
|
||||
logger.info("下载跨域pdf文件url:{}", urlPath);
|
||||
try {
|
||||
URL url = WebUtils.normalizedURL(urlPath);
|
||||
byte[] bytes = NetUtil.downloadBytes(url.toString());
|
||||
IOUtils.write(bytes, response.getOutputStream());
|
||||
} catch (IOException | GalimatiasParseException e) {
|
||||
byte[] bytes = DownloadUtils.getBytesFromUrl(urlPath);
|
||||
DownloadUtils.saveBytesToOutStream(bytes, response.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
logger.error("下载跨域pdf文件异常,url:{}", urlPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package cn.keking.web.filter;
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
@ -35,9 +34,6 @@ public class TrustHostFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
String url = getSourceUrl(request);
|
||||
if(url != null){
|
||||
url = new String(Base64Utils.decodeFromString(url), StandardCharsets.UTF_8);
|
||||
}
|
||||
String host = getHost(url);
|
||||
if (host != null &&!ConfigConstants.getTrustHostSet().isEmpty() && !ConfigConstants.getTrustHostSet().contains(host)) {
|
||||
String html = this.notTrustHost.replace("${current_host}", host);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user