Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
K
know-base
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
张京坤
know-base
Commits
f3739005
提交
f3739005
authored
1月 11, 2024
作者:
ZhangJingKun
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
在线编辑 zhangjingkun
上级
a25d5ae9
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
997 行增加
和
41 行删除
+997
-41
pom.xml
pom.xml
+12
-0
DocumentConstants.java
...in/java/com/zzsn/knowbase/constant/DocumentConstants.java
+51
-0
DocumentType.java
src/main/java/com/zzsn/knowbase/constant/DocumentType.java
+1
-1
ErrorCodeEnum.java
src/main/java/com/zzsn/knowbase/constant/ErrorCodeEnum.java
+75
-0
KbFileController.java
...n/java/com/zzsn/knowbase/controller/KbFileController.java
+68
-0
Document.java
src/main/java/com/zzsn/knowbase/entity/Document.java
+47
-0
DocumentEditParam.java
...main/java/com/zzsn/knowbase/entity/DocumentEditParam.java
+26
-0
DocumentService.java
src/main/java/com/zzsn/knowbase/service/DocumentService.java
+69
-0
ILocalFileService.java
...ain/java/com/zzsn/knowbase/service/ILocalFileService.java
+26
-1
DocumentServiceImpl.java
...a/com/zzsn/knowbase/service/impl/DocumentServiceImpl.java
+305
-0
LocalFileServiceImpl.java
.../com/zzsn/knowbase/service/impl/LocalFileServiceImpl.java
+191
-32
DocumentException.java
src/main/java/com/zzsn/knowbase/util/DocumentException.java
+26
-0
DefaultFileUtility.java
.../java/com/zzsn/knowbase/util/file/DefaultFileUtility.java
+10
-1
FileUtility.java
src/main/java/com/zzsn/knowbase/util/file/FileUtility.java
+2
-1
Md5Utils.java
src/main/java/com/zzsn/knowbase/util/file/Md5Utils.java
+74
-0
application.yml
src/main/resources/application.yml
+10
-1
KnowBaseApplicationTests.java
...test/java/com/zzsn/knowbase/KnowBaseApplicationTests.java
+4
-4
没有找到文件。
pom.xml
浏览文件 @
f3739005
...
@@ -160,6 +160,18 @@
...
@@ -160,6 +160,18 @@
<artifactId>
htmlcleaner
</artifactId>
<artifactId>
htmlcleaner
</artifactId>
<version>
2.25
</version>
<version>
2.25
</version>
</dependency>
</dependency>
<dependency>
<groupId>
org.hashids
</groupId>
<artifactId>
hashids
</artifactId>
<version>
1.0.3
</version>
</dependency>
<dependency>
<groupId>
com.googlecode.json-simple
</groupId>
<artifactId>
json-simple
</artifactId>
<version>
1.1
</version>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
src/main/java/com/zzsn/knowbase/constant/DocumentConstants.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
constant
;
import
java.time.Duration
;
/**
* @author: zhangcx
* @date: 2019/8/7 17:23
*/
public
class
DocumentConstants
{
public
static
final
String
HTTP_SCHEME
=
"http"
;
/**
* 支持的文档类型
*/
public
static
final
String
[]
FILE_TYPE_SUPPORT_VIEW
=
{
"doc"
,
"docx"
,
"xls"
,
"xlsx"
,
"ppt"
,
"pptx"
,
"txt"
,
"pdf"
};
/**
* 不支持编辑的类型
*/
public
static
final
String
[]
FILE_TYPE_UNSUPPORT_EDIT
=
{
"pdf"
};
/**
* 文档文件下载接口地址
*/
public
static
final
String
OFFICE_API_DOC_FILE
=
"%s/download%s"
;
/**
* 文档信息获取地址
*/
public
static
final
String
OFFICE_API_DOC
=
"%s/api/doc/%s"
;
/**
* 编辑回调地址
*/
public
static
final
String
OFFICE_API_CALLBACK
=
"%s/callback"
;
/**
* 预览地址
*/
public
static
final
String
OFFICE_VIEWER
=
"%s/viewer/%s"
;
/**
* 编辑地址
*/
public
static
final
String
OFFICE_EDITOR
=
"%s/editor/%s"
;
/**
* 文档redis缓存前缀 格式化
*/
public
static
final
String
DOCUMENT_REDIS_KEY_PREFIX_FORMAT
=
"onlyoffice:document:%s"
;
/**
* 缓存过期时间: 1天
*/
public
static
final
Duration
CACHE_DURATION
=
Duration
.
ofDays
(
1
);
public
static
final
String
HASH_KEY
=
"lezhixing"
;
}
src/main/java/com/zzsn/knowbase/
enums
/DocumentType.java
→
src/main/java/com/zzsn/knowbase/
constant
/DocumentType.java
浏览文件 @
f3739005
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
*
*
*/
*/
package
com
.
zzsn
.
knowbase
.
enums
;
package
com
.
zzsn
.
knowbase
.
constant
;
public
enum
DocumentType
{
public
enum
DocumentType
{
word
,
word
,
...
...
src/main/java/com/zzsn/knowbase/constant/ErrorCodeEnum.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
constant
;
import
org.apache.commons.lang3.StringUtils
;
import
java.util.Arrays
;
/**
* 错误码枚举
* 约定 code 为 0 表示操作成功,
* 1 或 2 等正数表示软件错误,
* -1, -2 等负数表示系统错误.
* @author: zhangcx
* @date: 2019/8/12 13:18
*/
public
enum
ErrorCodeEnum
{
SUCCESS
(
"0"
,
"success"
),
DOC_FILE_NOT_EXISTS
(
"1001"
,
"目标文档不存在"
),
DOC_FILE_EMPTY
(
"1002"
,
"目标文档是目录或空文件"
),
DOC_FILE_UNREADABLE
(
"1003"
,
"目标文档不可读"
),
DOC_FILE_OVERSIZE
(
"1004"
,
"目标文档大小超过限制"
),
DOC_FILE_TYPE_UNSUPPORTED
(
"1005"
,
"目标文档格式不正确"
),
DOC_FILE_MD5_ERROR
(
"1006"
,
"目标文档md5校验失败"
),
DOC_FILE_MIME_ERROR
(
"1007"
,
"目标文档MIME检查失败"
),
DOC_FILE_NO_EXTENSION
(
"1008"
,
"文件路径不包含扩展名"
),
DOC_FILE_EXTENSION_NOT_MATCH
(
"1009"
,
"文件路径和名称后缀不匹配"
),
DOC_FILE_KEY_ERROR
(
"1010"
,
"目标文档key计算失败"
),
DOC_CACHE_ERROR
(
"1101"
,
"文档信息缓存失败"
),
DOC_CACHE_NOT_EXISTS
(
"1102"
,
"从缓存中获取文档信息失败"
),
UNSUPPORTED_REQUEST_METHOD
(
"1201"
,
"不支持的请求类型"
),
SYSTEM_UNKNOWN_ERROR
(
"-1"
,
"系统繁忙,请稍后再试..."
);
private
String
code
;
private
String
msg
;
ErrorCodeEnum
(
String
code
,
String
msg
)
{
this
.
code
=
code
;
this
.
msg
=
msg
;
}
public
String
getCode
()
{
return
code
;
}
public
String
getMsg
()
{
return
msg
;
}
@Override
public
String
toString
()
{
return
"ErrorCodeEnum{"
+
"code='"
+
code
+
'\''
+
", msg='"
+
msg
+
'\''
+
'}'
;
}
public
boolean
isSuccessful
()
{
return
this
.
code
==
ErrorCodeEnum
.
SUCCESS
.
getCode
();
}
public
boolean
isFailed
()
{
return
!
isSuccessful
();
}
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
"| 代码 | 描述 |"
);
System
.
out
.
println
(
"| ---- | ---- |"
);
Arrays
.
stream
(
ErrorCodeEnum
.
values
()).
forEach
((
ce
)
->
{
System
.
out
.
println
(
"| "
+
StringUtils
.
rightPad
(
ce
.
getCode
(),
4
)
+
" | "
+
ce
.
getMsg
()
+
" |"
);
});
}
}
src/main/java/com/zzsn/knowbase/controller/KbFileController.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
controller
;
import
com.zzsn.knowbase.service.ILocalFileService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.ui.Model
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* @Version 1.0
* @Author: ZhangJingKun
* @Date: 2024/1/10 10:18
* @Content:
*/
@RestController
@RequestMapping
(
"/api/file"
)
public
class
KbFileController
{
@Autowired
private
ILocalFileService
localFileService
;
/**
* 下载文档接口
* @param fileName
* @param filePath
* @param response
*/
@GetMapping
(
"/download"
)
public
void
download
(
String
fileName
,
String
filePath
,
HttpServletResponse
response
)
{
localFileService
.
download
(
fileName
,
filePath
,
response
);
}
/**
* 编辑文档接口
* @param fileName
* @param filePath
* @param userName
* @param model
* @return
*/
@GetMapping
(
"/edit"
)
public
String
editDocFile
(
String
fileName
,
String
filePath
,
String
userName
,
Model
model
)
{
return
localFileService
.
editDocFile
(
fileName
,
filePath
,
userName
,
model
);
}
/**
* 编辑文档时的回调接口
* @param request
* @param response
* @throws IOException
*/
@RequestMapping
(
"/callback"
)
public
void
saveDocumentFile
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
//处理编辑回调逻辑
localFileService
.
callBack
(
request
,
response
);
}
}
src/main/java/com/zzsn/knowbase/entity/Document.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
entity
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.io.Serializable
;
/**
* onlyoffice定义的文档对象
* @author: zhangcx
* @date: 2019/8/7 16:30
*/
@ApiModel
(
"文档实体"
)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public
class
Document
implements
Serializable
{
/** 【必需】文件唯一标识 */
@ApiModelProperty
(
value
=
"文档 key"
,
example
=
"xYz123"
)
private
String
key
;
/** 【必需】文档名称 */
@ApiModelProperty
(
value
=
"文档标题"
,
example
=
"test.doc"
)
private
String
title
;
/** 【必需】文档后缀 */
@ApiModelProperty
(
value
=
"文档类型"
,
example
=
"doc"
)
private
String
fileType
;
/** mimeType 应该先校验文件是否可以打开(非api必须字段) */
//private String mimeType;
/** 文件实体在服务器硬盘存储位置 */
@ApiModelProperty
(
value
=
"文档物理存储位置"
,
example
=
"/temp/test.doc"
)
private
String
storage
;
/** 【必需】文件实体下载地址 */
@ApiModelProperty
(
value
=
"文档获取url"
,
example
=
"http://192.168.0.58:20053/api/file/xYz123"
)
private
String
url
;
/** 打开文件预览/编辑的链接 */
//private String refrence;
/** 文档打开方式 {@link OpenModeEnum} */
//private String mode;
}
src/main/java/com/zzsn/knowbase/entity/DocumentEditParam.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
entity
;
import
lombok.Builder
;
import
lombok.Data
;
/**
* 文档编辑时参数 实体
* @author: zhangcx
* @date: 2019/8/26 14:50
*/
@Data
@Builder
public
class
DocumentEditParam
{
/** 当前打开编辑页面的用户信息 */
private
UserBean
user
;
/** onlyoffice在编辑时请求的回调地址,必选项 */
private
String
callbackUrl
;
@Data
@Builder
public
static
class
UserBean
{
/** 用户id */
private
String
id
;
/** 用户姓名 */
private
String
name
;
}
}
src/main/java/com/zzsn/knowbase/service/DocumentService.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
service
;
import
com.zzsn.knowbase.entity.Document
;
import
com.zzsn.knowbase.entity.DocumentEditParam
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* 文档业务 接口
* @author: zhangcx
* @date: 2019/8/7 16:30
*/
public
interface
DocumentService
{
/**
* 构建文档对象
* @param filePath
* @param fileName
* @return documentKey 文档key
*/
String
buildDocument
(
String
filePath
,
String
fileName
);
/**
* 从缓从中获取文档信息
* @param documentKey
* @return
*/
Document
getDocument
(
String
documentKey
);
/**
* 下载文档实体文件
* @param documentKey
* @param request
* @param response
* @throws IOException
*/
void
downloadDocumentFile
(
String
documentKey
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
;
/**
* 构建文档编辑参数 对象
* @param userId
* @param userName
* @return
*/
DocumentEditParam
buildDocumentEditParam
(
String
userId
,
String
userName
,
String
fileName
);
/**
* 编辑后保存文档实体文件
* @param documentKey
* @param downloadUrl
* @throws IOException
*/
boolean
saveDocumentFile
(
String
documentKey
,
String
downloadUrl
)
throws
IOException
;
/**
* 获取服务暴露的host(包含端口)
* @return
*/
Object
getServerHost
();
/**
* 文档是否支持编辑
* @param document
* @return
*/
boolean
canEdit
(
Document
document
);
}
src/main/java/com/zzsn/knowbase/service/ILocalFileService.java
浏览文件 @
f3739005
...
@@ -4,8 +4,12 @@ import com.zzsn.knowbase.entity.KnowFile;
...
@@ -4,8 +4,12 @@ import com.zzsn.knowbase.entity.KnowFile;
import
com.zzsn.knowbase.vo.Result
;
import
com.zzsn.knowbase.vo.Result
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.ui.Model
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -33,11 +37,32 @@ public interface ILocalFileService {
...
@@ -33,11 +37,32 @@ public interface ILocalFileService {
/**
/**
* 文件下载
* 文件下载
* @param
* @param
* @return
*/
//ResponseEntity<Resource> download(String fileName, String filePath);
void
download
(
String
fileName
,
String
filePath
,
HttpServletResponse
response
);
/**
* 编辑文档
* @param fileName
* @param fileName
* @param filePath
* @param filePath
* @param userName
* @param model
* @return
* @return
*/
*/
ResponseEntity
<
Resource
>
download
(
String
fileName
,
String
filePath
);
String
editDocFile
(
String
fileName
,
String
filePath
,
String
userName
,
Model
model
);
/**
* 编辑文档时的回调接口
* @param request
* @param response
* @throws IOException
*/
void
callBack
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
;
}
}
src/main/java/com/zzsn/knowbase/service/impl/DocumentServiceImpl.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
service
.
impl
;
import
com.alibaba.fastjson.JSON
;
import
com.zzsn.knowbase.constant.DocumentConstants
;
import
com.zzsn.knowbase.constant.ErrorCodeEnum
;
import
com.zzsn.knowbase.entity.Document
;
import
com.zzsn.knowbase.entity.DocumentEditParam
;
import
com.zzsn.knowbase.service.DocumentService
;
import
com.zzsn.knowbase.util.DocumentException
;
import
com.zzsn.knowbase.util.file.Md5Utils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.io.FileUtils
;
import
org.apache.commons.io.FilenameUtils
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.hashids.Hashids
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.core.env.Environment
;
import
org.springframework.stereotype.Service
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.*
;
import
java.net.URL
;
import
java.nio.file.Files
;
import
java.nio.file.Paths
;
/**
* 文档相关业务方法
*
* @author: zhangcx
* @date: @date: 2019/8/7 16:30
*/
@Slf4j
@Service
public
class
DocumentServiceImpl
implements
DocumentService
{
@Autowired
Environment
environment
;
@Value
(
"${document.server.host}"
)
private
String
serverHost
;
/**
* 大小限制,默认10M
*/
@Value
(
"${document.file-size.limit:10485760}"
)
private
Long
docFileSizeLimit
;
@Value
(
"${files.docservice.url.site}"
)
private
String
documentServerHost
;
@Value
(
"${files.docservice.url.api}"
)
private
String
documentServerApiJs
;
// @Autowired
//private DocumentCacheService cacheService;
@Override
public
String
buildDocument
(
String
filePath
,
String
fileName
)
{
if
(
StringUtils
.
isBlank
(
filePath
))
{
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_NOT_EXISTS
);
}
filePath
=
FilenameUtils
.
normalize
(
filePath
);
String
fileType
=
StringUtils
.
lowerCase
(
FilenameUtils
.
getExtension
(
filePath
));
if
(
StringUtils
.
isBlank
(
fileType
))
{
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_NO_EXTENSION
);
}
// 如果指定了文件名,则需要校验和实体文件格式是否一致
if
(
StringUtils
.
isNotBlank
(
fileName
)
&&
!
fileType
.
equalsIgnoreCase
(
FilenameUtils
.
getExtension
(
fileName
)))
{
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_EXTENSION_NOT_MATCH
);
}
File
docFile
=
new
File
(
filePath
);
// 校验文件实体
preFileCheck
(
docFile
);
fileName
=
StringUtils
.
isNotBlank
(
fileName
)
?
fileName
:
docFile
.
getName
();
String
fileKey
=
this
.
fileKey
(
docFile
,
fileName
);
Document
document
=
Document
.
builder
()
.
fileType
(
fileType
)
.
title
(
fileName
)
.
storage
(
filePath
)
.
build
();
boolean
cached
=
false
;
// try {
// cached = cacheService.put(fileKey, document);
// } catch (Exception e) {
// log.error("$$$ 缓存失败~~", e);
// }
// if (!cached) {
// throw new DocumentException(ErrorCodeEnum.DOC_CACHE_ERROR);
// }
document
.
setKey
(
fileKey
);
return
JSON
.
toJSONString
(
document
);
}
@Override
public
Document
getDocument
(
String
documentKey
)
{
Document
doc
=
null
;
try
{
doc
=
JSON
.
parseObject
(
documentKey
,
Document
.
class
);
}
catch
(
Exception
e
)
{
log
.
error
(
"$$$ 获取缓存失败~~"
,
e
);
}
if
(
doc
==
null
)
{
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_CACHE_NOT_EXISTS
);
}
// 从缓存中取出后,再绑定非必需缓存字段(节省缓存大小)
// doc.setKey(documentKey);
doc
.
setUrl
(
fileUrl
(
doc
.
getTitle
()));
if
(
log
.
isDebugEnabled
())
{
log
.
info
(
doc
.
toString
());
}
return
doc
;
}
/**
* 计算文件key值: 文件md5值+路径的短md5值+名称的短md5值
* @param docFile
* @param name 生成协作时文档的docuemnt.key的值
* @return
*/
public
String
fileKey
(
File
docFile
,
String
name
)
{
String
docFileMd5
=
Md5Utils
.
getFileMd5
(
docFile
);
if
(
StringUtils
.
isBlank
(
docFileMd5
))
{
log
.
error
(
"$$$ 构建文件信息失败!计算文件 md5 失败!"
);
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_MD5_ERROR
);
}
String
pathShortMd5
=
Md5Utils
.
md5
(
docFile
.
getAbsolutePath
());
String
nameShortMd5
=
Md5Utils
.
md5
(
name
);
Hashids
hashids
=
new
Hashids
(
DocumentConstants
.
HASH_KEY
);
// (将路径字符串短md5值 + 名称字符串短md5值) ==> 再转成短id形式 ==> 作为文档的key(暂且认为是不会重复的)
String
key
=
hashids
.
encodeHex
(
String
.
format
(
"%s%s%s"
,
docFileMd5
,
pathShortMd5
,
nameShortMd5
));
if
(
StringUtils
.
isBlank
(
key
))
{
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_KEY_ERROR
);
}
return
key
;
}
/**
* 文件key值
* @param fileType
* @param docCrc32
* @return
*/
private
String
fileKey
(
String
fileType
,
String
docCrc32
)
{
return
String
.
format
(
"%s_%s"
,
fileType
,
docCrc32
);
}
/**
* 文件url地址
* @param
* @return
*/
private
String
fileUrl
(
String
filename
)
{
return
String
.
format
(
DocumentConstants
.
OFFICE_API_DOC_FILE
,
getServerHost
(),
"?name="
+
filename
);
// return "http://192.168.0.58:20053/download?name="+filename;
}
/**
* 根据文档信息下载文档文件
* @param documentKey
* @param request
* @param response
* @throws IOException
*/
@Override
public
void
downloadDocumentFile
(
String
documentKey
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
Document
doc
=
this
.
getDocument
(
documentKey
);
File
file
=
new
File
(
doc
.
getStorage
());
try
(
InputStream
reader
=
new
FileInputStream
(
file
);
OutputStream
out
=
response
.
getOutputStream
())
{
byte
[]
buf
=
new
byte
[(
int
)
FileUtils
.
ONE_KB
];
int
len
=
0
;
//response.setContentType(mimeType(file));
while
((
len
=
reader
.
read
(
buf
))
!=
-
1
)
{
out
.
write
(
buf
,
0
,
len
);
}
out
.
flush
();
}
catch
(
Exception
e
)
{
log
.
error
(
"下载失败!读取文件["
+
doc
.
getStorage
()
+
"]报错~~"
,
e
);
}
}
@Override
public
DocumentEditParam
buildDocumentEditParam
(
String
userId
,
String
userName
,
String
fileName
)
{
return
DocumentEditParam
.
builder
()
.
callbackUrl
(
callbackUrl
(
fileName
))
.
user
(
DocumentEditParam
.
UserBean
.
builder
()
.
id
(
userId
)
.
name
(
userName
)
.
build
())
.
build
();
}
private
String
callbackUrl
(
String
fileName
)
{
String
format
=
String
.
format
(
DocumentConstants
.
OFFICE_API_CALLBACK
,
getServerHost
());
format
=
format
+
"?fileName="
+
fileName
;
return
format
;
}
/**
* 上传文档实体文件
* @param documentKey
* @param downloadUrl
* @throws IOException
*/
@Override
public
boolean
saveDocumentFile
(
String
documentKey
,
String
downloadUrl
)
{
if
(
log
.
isInfoEnabled
())
{
log
.
info
(
downloadUrl
);
}
// TODO 默认覆盖源文件,如果调用者指定,则存到临时目录?
boolean
isCover
=
true
;
Document
doc
=
this
.
getDocument
(
documentKey
);
String
saveFilePath
=
doc
.
getStorage
();
// if (!isCover) {
// String baseDir = environment.getProperty("java.io.tmpdir");
// saveFilePath = String.format("%s/office-api/%s/%s.%s", baseDir, documentKey, System.currentTimeMillis(), doc.getFileType());
// }
File
saveFile
=
new
File
(
saveFilePath
);
boolean
success
=
false
;
try
{
FileUtils
.
copyURLToFile
(
new
URL
(
downloadUrl
),
saveFile
);
if
(
saveFile
.
exists
()
&&
saveFile
.
length
()
>
0
)
{
success
=
true
;
}
}
catch
(
IOException
e
)
{
log
.
error
(
"$$$ 保存文档失败!"
,
e
);
}
return
success
;
//TODO 编辑成功后,应该删除之前的编辑状态缓存
}
@Override
public
Object
getServerHost
()
{
if
(
StringUtils
.
startsWith
(
serverHost
,
DocumentConstants
.
HTTP_SCHEME
))
{
return
serverHost
;
}
return
String
.
format
(
"http://%s"
,
serverHost
);
}
@Override
public
boolean
canEdit
(
Document
document
)
{
if
(
ArrayUtils
.
contains
(
DocumentConstants
.
FILE_TYPE_UNSUPPORT_EDIT
,
document
.
getFileType
()))
{
return
false
;
}
return
true
;
}
/**
* 获取文档信息api地址
* @param docId
* @return
*/
private
String
docInfoUrl
(
String
docId
)
{
return
String
.
format
(
DocumentConstants
.
OFFICE_API_DOC
,
getServerHost
(),
docId
);
}
/**
* 获取文件的 mimetype
* @param file
* @deprecated
* @return
*/
@Deprecated
private
String
mimeType
(
File
file
)
{
try
{
return
Files
.
probeContentType
(
Paths
.
get
(
file
.
toURI
()));
}
catch
(
IOException
e
)
{
log
.
error
(
"$$$ 获取文件mimeType错误!"
,
e
);
}
return
null
;
}
/**
* 先校验文档文件
* @param docFile
* @return
*/
private
void
preFileCheck
(
File
docFile
)
{
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"### 开始校验文档:[{}]"
,
docFile
.
getAbsolutePath
());
}
if
(
docFile
==
null
||
!
docFile
.
exists
())
{
log
.
error
(
"$$$ 目标文档不存在,无法打开!"
);
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_NOT_EXISTS
);
}
if
(
docFile
.
isDirectory
()
||
docFile
.
length
()
<=
0
)
{
log
.
error
(
"$$$ 目标文档[{}]是目录或空文件,无法打开!"
,
docFile
.
getAbsolutePath
());
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_EMPTY
);
}
if
(!
docFile
.
canRead
())
{
log
.
error
(
"$$$ 目标文档[{}]不可读,无法打开!"
,
docFile
.
getAbsolutePath
());
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_UNREADABLE
);
}
if
(
docFile
.
length
()
>
docFileSizeLimit
)
{
log
.
error
(
"$$$ 目标文档大小超过限制({}B > {}B),无法打开!"
,
docFile
.
length
(),
docFileSizeLimit
);
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_OVERSIZE
);
}
String
ext
=
StringUtils
.
lowerCase
(
FilenameUtils
.
getExtension
(
docFile
.
getName
()));
if
(!
ArrayUtils
.
contains
(
DocumentConstants
.
FILE_TYPE_SUPPORT_VIEW
,
ext
))
{
log
.
error
(
"$$$ 目标文档格式[{}]不正确,无法打开!(只支持:{})"
,
ext
,
StringUtils
.
join
(
DocumentConstants
.
FILE_TYPE_SUPPORT_VIEW
,
","
));
throw
new
DocumentException
(
ErrorCodeEnum
.
DOC_FILE_TYPE_UNSUPPORTED
);
}
}
}
src/main/java/com/zzsn/knowbase/service/impl/LocalFileServiceImpl.java
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
service
.
impl
;
package
com
.
zzsn
.
knowbase
.
service
.
impl
;
import
com.zzsn.knowbase.constant.Constants
;
import
com.zzsn.knowbase.entity.Document
;
import
com.zzsn.knowbase.entity.KnowFile
;
import
com.zzsn.knowbase.entity.KnowFile
;
import
com.zzsn.knowbase.service.DocumentService
;
import
com.zzsn.knowbase.service.ILocalFileService
;
import
com.zzsn.knowbase.service.ILocalFileService
;
import
com.zzsn.knowbase.util.CodeGenerateUtil
;
import
com.zzsn.knowbase.util.file.FileUtility
;
import
com.zzsn.knowbase.util.file.FileUtility
;
import
com.zzsn.knowbase.vo.Result
;
import
com.zzsn.knowbase.vo.Result
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.json.simple.JSONObject
;
import
org.json.simple.parser.JSONParser
;
import
org.json.simple.parser.ParseException
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.UrlResource
;
import
org.springframework.core.io.UrlResource
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.ui.Model
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.File
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.IOException
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.*
;
import
java.net.MalformedURLException
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.net.URLEncoder
;
import
java.nio.file.Files
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.nio.file.Paths
;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.util.ArrayList
;
import
java.util.*
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.UUID
;
/**
/**
* @Version 1.0
* @Version 1.0
...
@@ -36,7 +44,13 @@ import java.util.UUID;
...
@@ -36,7 +44,13 @@ import java.util.UUID;
public
class
LocalFileServiceImpl
implements
ILocalFileService
{
public
class
LocalFileServiceImpl
implements
ILocalFileService
{
@Autowired
@Autowired
private
FileUtility
fileUtility
;
private
FileUtility
fileUtility
;
//文件工具类
@Autowired
private
CodeGenerateUtil
codeGenerateUtil
;
//生成唯一id
@Autowired
private
DocumentService
documentService
;
@Value
(
"${files.storage}"
)
@Value
(
"${files.storage}"
)
String
filesStorage
;
String
filesStorage
;
...
@@ -44,8 +58,9 @@ public class LocalFileServiceImpl implements ILocalFileService {
...
@@ -44,8 +58,9 @@ public class LocalFileServiceImpl implements ILocalFileService {
@Override
@Override
public
Result
<
KnowFile
>
upload
(
MultipartFile
file
)
{
public
Result
<
KnowFile
>
upload
(
MultipartFile
file
)
{
try
{
try
{
String
fullFileName
=
file
.
getOriginalFilename
();
// get file name
String
fileName
=
file
.
getOriginalFilename
();
// 获取文件名称
String
fileExtension
=
fileUtility
.
getFileExtension
(
fullFileName
);
// get file extension
String
fileExtension
=
fileUtility
.
getFileExtension
(
fileName
);
// 获取文件扩展名
String
fileType
=
fileUtility
.
getFileType
(
fileName
);
//获取文件类型
long
fileSize
=
file
.
getSize
();
// get file size
long
fileSize
=
file
.
getSize
();
// get file size
// check if the file size exceeds the maximum file size or is less than 0
// check if the file size exceeds the maximum file size or is less than 0
...
@@ -59,21 +74,17 @@ public class LocalFileServiceImpl implements ILocalFileService {
...
@@ -59,21 +74,17 @@ public class LocalFileServiceImpl implements ILocalFileService {
return
result
;
return
result
;
}
}
String
fileName
=
file
.
getOriginalFilename
();
String
fileId
=
codeGenerateUtil
.
geneIdNo
(
Constants
.
FINANCE
,
8
);
String
fileSuffix
=
getFileSuffix
(
fileName
);
String
filePath
=
getFilePath
()
+
fileId
+
fileExtension
;
//byte[] bytes = file.getBytes(); // get file in bytes
String
uid
=
UUID
.
randomUUID
().
toString
();
String
filePath
=
getFilePath
()
+
uid
+
"."
+
fileSuffix
;
byte
[]
bytes
=
file
.
getBytes
();
// get file in bytes
//Files.write(Paths.get(filePath), bytes);
//Files.write(Paths.get(filePath), bytes);
file
.
transferTo
(
new
File
(
filePath
));
file
.
transferTo
(
new
File
(
file
sStorage
+
file
Path
));
KnowFile
knowFile
=
new
KnowFile
();
KnowFile
knowFile
=
new
KnowFile
();
knowFile
.
setFileId
(
ui
d
);
knowFile
.
setFileId
(
fileI
d
);
knowFile
.
setFileName
(
fileName
);
knowFile
.
setFileName
(
fileName
);
knowFile
.
setFilePath
(
filePath
);
knowFile
.
setFilePath
(
filePath
);
knowFile
.
setFileType
(
file
Suffix
);
knowFile
.
setFileType
(
file
Type
);
knowFile
.
setFileSize
(
fileSize
);
knowFile
.
setFileSize
(
fileSize
);
Result
result
=
Result
.
OK
(
knowFile
);
Result
result
=
Result
.
OK
(
knowFile
);
return
result
;
// create user metadata and return it
return
result
;
// create user metadata and return it
...
@@ -96,11 +107,163 @@ public class LocalFileServiceImpl implements ILocalFileService {
...
@@ -96,11 +107,163 @@ public class LocalFileServiceImpl implements ILocalFileService {
return
list
;
return
list
;
}
}
@Override
public
void
download
(
String
fileName
,
String
filePath
,
HttpServletResponse
response
)
{
// path是指想要下载的文件的路径
File
file
=
new
File
(
filesStorage
+
filePath
);
try
{
// 将文件写入输入流
FileInputStream
fileInputStream
=
new
FileInputStream
(
file
);
InputStream
fis
=
new
BufferedInputStream
(
fileInputStream
);
byte
[]
buffer
=
new
byte
[
fis
.
available
()];
fis
.
read
(
buffer
);
fis
.
close
();
// 清空response
response
.
reset
();
// 设置response的Header
response
.
setCharacterEncoding
(
"UTF-8"
);
//Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
//attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
// filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
response
.
addHeader
(
"Content-Disposition"
,
"attachment;filename="
+
URLEncoder
.
encode
(
fileName
,
"UTF-8"
));
// 告知浏览器文件的大小
response
.
addHeader
(
"Content-Length"
,
""
+
file
.
length
());
OutputStream
outputStream
=
new
BufferedOutputStream
(
response
.
getOutputStream
());
response
.
setContentType
(
"application/octet-stream"
);
outputStream
.
write
(
buffer
);
outputStream
.
flush
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
//edit
@Override
public
String
editDocFile
(
String
fileName
,
String
filePath
,
String
userName
,
Model
model
)
{
String
path
=
filePath
;
Document
document
=
documentService
.
getDocument
(
documentService
.
buildDocument
(
path
,
fileName
));
model
.
addAttribute
(
"document"
,
document
);
// 如果该格式不支持编辑,则返回预览页面
if
(!
documentService
.
canEdit
(
document
))
{
return
"/demo"
;
}
model
.
addAttribute
(
"documentEditParam"
,
documentService
.
buildDocumentEditParam
(
userName
,
userName
,
fileName
));
return
"/editor"
;
}
//编辑文档时回调接口
@Override
public
void
callBack
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
PrintWriter
writer
=
null
;
JSONObject
jsonObj
=
null
;
System
.
out
.
println
(
"===saveeditedfile------------"
);
try
{
writer
=
response
.
getWriter
();
Scanner
scanner
=
new
Scanner
(
request
.
getInputStream
()).
useDelimiter
(
"\\A"
);
String
body
=
scanner
.
hasNext
()
?
scanner
.
next
()
:
""
;
jsonObj
=
(
JSONObject
)
new
JSONParser
().
parse
(
body
);
System
.
out
.
println
(
jsonObj
);
System
.
out
.
println
(
"===saveeditedfile:"
+
jsonObj
.
get
(
"status"
));
/*
0-找不到具有密钥标识符的文档,
1-文档正在编辑,
2-文档已准备好保存,
3-发生文档保存错误,
4-文档已关闭,没有任何更改,
6-文档正在编辑,但当前文档状态已保存,
7-强制保存文档时发生错误。
*/
if
((
long
)
jsonObj
.
get
(
"status"
)
==
2
)
{
callBackSaveDocument
(
jsonObj
,
request
,
response
);
}
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
ParseException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
/*
* status = 1,我们给onlyoffice的服务返回{"error":"0"}的信息,这样onlyoffice会认为回调接口是没问题的,这样就可以在线编辑文档了,否则的话会弹出窗口说明
* 在线编辑还没有关闭,前端有人下载文档时,强制保存最新内容 当status 是6时说明有人在编辑时下载文档
* */
System
.
out
.
println
(
jsonObj
.
get
(
"status"
));
if
((
long
)
jsonObj
.
get
(
"status"
)
==
6
)
{
//处理当文档正在编辑为关闭时,下载文档
if
(((
String
)
jsonObj
.
get
(
"userdata"
)).
equals
(
"sample userdata"
)){
callBackSaveDocument
(
jsonObj
,
request
,
response
);
}
System
.
out
.
println
(
"====保存失败:"
);
writer
.
write
(
"{\"error\":1}"
);
}
else
{
//执行删除编辑时下载保存的文件:
deleteTempFile
(
request
.
getParameter
(
"fileName"
));
writer
.
write
(
"{\"error\":0}"
);
}
}
/**
* 编辑以后保存文件
* @param jsonObj
* @param request
* @param response
* @throws IOException
*/
public
void
callBackSaveDocument
(
JSONObject
jsonObj
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
/*
* 当我们关闭编辑窗口后,十秒钟左右onlyoffice会将它存储的我们的编辑后的文件,,此时status = 2,通过request发给我们,我们需要做的就是接收到文件然后回写该文件。
* */
/*
* 定义要与文档存储服务保存的编辑文档的链接。当状态值仅等于2或3时,存在链路。
* */
String
downloadUri
=
(
String
)
jsonObj
.
get
(
"url"
);
System
.
out
.
println
(
"====文档编辑完成,现在开始保存编辑后的文档,其下载地址为:"
+
downloadUri
);
//解析得出文件名
//String fileName = downloadUri.substring(downloadUri.lastIndexOf('/')+1);
String
fileName
=
request
.
getParameter
(
"fileName"
);
System
.
out
.
println
(
"====下载的文件名:"
+
fileName
);
URL
url
=
new
URL
(
downloadUri
);
java
.
net
.
HttpURLConnection
connection
=
(
java
.
net
.
HttpURLConnection
)
url
.
openConnection
();
InputStream
stream
=
connection
.
getInputStream
();
//更换为实际的路径F:\DataOfHongQuanzheng\java\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Java Example\\app_data\192.168.56.1\
//File savedFile = new File("F:\\DataOfHongQuanzheng\\onlyoffice_data\\app_data\\"+fileName);
File
savedFile
=
new
File
(
filesStorage
+
fileName
);
if
(
null
!=((
String
)
jsonObj
.
get
(
"userdata"
))&&((
String
)
jsonObj
.
get
(
"userdata"
)).
equals
(
"sample userdata"
))
{
savedFile
=
new
File
(
filesStorage
+
"v1"
+
fileName
);
}
try
(
FileOutputStream
out
=
new
FileOutputStream
(
savedFile
))
{
int
read
;
final
byte
[]
bytes
=
new
byte
[
1024
];
while
((
read
=
stream
.
read
(
bytes
))
!=
-
1
)
{
out
.
write
(
bytes
,
0
,
read
);
}
out
.
flush
();
}
connection
.
disconnect
();
}
public
void
deleteTempFile
(
String
fileName
)
{
//因为临时存储的文件都添加了v1前缀所以删除文件时需要在文件名测前边加一个v1
File
file
=
new
File
(
filesStorage
+
"v1"
+
fileName
);
if
(
file
.
exists
())
{
file
.
delete
();
}
}
/**
/**
* 文件下载
* 文件下载
*/
*/
/*
@Override
@Override
public ResponseEntity<Resource> download(String fileName, String filePath) {
public ResponseEntity<Resource> download(String fileName, String filePath) {
Path path = Paths.get(filePath);
Path path = Paths.get(filePath);
...
@@ -118,15 +281,20 @@ public class LocalFileServiceImpl implements ILocalFileService {
...
@@ -118,15 +281,20 @@ public class LocalFileServiceImpl implements ILocalFileService {
throw new RuntimeException("文件读取失败");
throw new RuntimeException("文件读取失败");
}
}
}
}
*/
//获取文件夹路径
//生成文件夹路径
private
String
getFilePath
(){
private
String
getFilePath
(){
LocalDate
currentDate
=
LocalDate
.
now
();
LocalDate
currentDate
=
LocalDate
.
now
();
//System.out.println("当前日期: " + currentDate
);
String
current
=
currentDate
.
toString
().
replace
(
"-"
,
""
);
String
filePath
=
filesStorage
+
currentDate
+
"/"
;
String
filePath
=
current
+
"/"
;
//判断文件夹是否存在,不存在创建
//判断文件夹是否存在,不存在创建
Path
directory
=
Paths
.
get
(
filePath
);
Path
directory
=
Paths
.
get
(
file
sStorage
+
file
Path
);
if
(!
Files
.
exists
(
directory
))
{
if
(!
Files
.
exists
(
directory
))
{
try
{
try
{
Files
.
createDirectories
(
directory
);
Files
.
createDirectories
(
directory
);
...
@@ -138,14 +306,5 @@ public class LocalFileServiceImpl implements ILocalFileService {
...
@@ -138,14 +306,5 @@ public class LocalFileServiceImpl implements ILocalFileService {
}
}
return
filePath
;
return
filePath
;
}
}
//获取文件后缀
private
String
getFileSuffix
(
String
fileName
){
int
lastIndexOfDot
=
fileName
.
lastIndexOf
(
'.'
);
String
fileExtension
=
""
;
if
(
lastIndexOfDot
!=
-
1
)
{
fileExtension
=
fileName
.
substring
(
lastIndexOfDot
+
1
);
}
return
fileExtension
;
}
}
}
src/main/java/com/zzsn/knowbase/util/DocumentException.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
util
;
import
com.zzsn.knowbase.constant.ErrorCodeEnum
;
/**
* 文档异常封装类
* @author zhangcx
*/
public
final
class
DocumentException
extends
RuntimeException
{
private
ErrorCodeEnum
errorCode
;
public
DocumentException
(
ErrorCodeEnum
errorCode
)
{
super
(
errorCode
.
getMsg
());
this
.
errorCode
=
errorCode
;
}
public
DocumentException
(
ErrorCodeEnum
errorCode
,
Throwable
t
)
{
super
(
errorCode
.
getMsg
(),
t
);
this
.
errorCode
=
errorCode
;
}
public
ErrorCodeEnum
getErrorCode
()
{
return
errorCode
;
}
}
src/main/java/com/zzsn/knowbase/util/file/DefaultFileUtility.java
浏览文件 @
f3739005
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
package
com
.
zzsn
.
knowbase
.
util
.
file
;
package
com
.
zzsn
.
knowbase
.
util
.
file
;
import
com.zzsn.knowbase.constant.Constants
;
import
com.zzsn.knowbase.constant.Constants
;
import
com.zzsn.knowbase.
enums
.DocumentType
;
import
com.zzsn.knowbase.
constant
.DocumentType
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
...
@@ -123,6 +123,15 @@ public class DefaultFileUtility implements FileUtility {
...
@@ -123,6 +123,15 @@ public class DefaultFileUtility implements FileUtility {
String
fileExt
=
fileName
.
substring
(
fileName
.
lastIndexOf
(
"."
));
String
fileExt
=
fileName
.
substring
(
fileName
.
lastIndexOf
(
"."
));
return
fileExt
.
toLowerCase
();
return
fileExt
.
toLowerCase
();
}
}
//get file type from URL
public
String
getFileType
(
final
String
url
)
{
String
fileName
=
getFileName
(
url
);
if
(
fileName
==
null
)
{
return
null
;
}
String
fileExt
=
fileName
.
substring
(
fileName
.
lastIndexOf
(
"."
));
return
fileExt
.
toLowerCase
();
}
// get an editor internal extension
// get an editor internal extension
public
String
getInternalExtension
(
final
DocumentType
type
)
{
public
String
getInternalExtension
(
final
DocumentType
type
)
{
...
...
src/main/java/com/zzsn/knowbase/util/file/FileUtility.java
浏览文件 @
f3739005
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
package
com
.
zzsn
.
knowbase
.
util
.
file
;
package
com
.
zzsn
.
knowbase
.
util
.
file
;
import
com.zzsn.knowbase.
enums
.DocumentType
;
import
com.zzsn.knowbase.
constant
.DocumentType
;
import
java.nio.file.Path
;
import
java.nio.file.Path
;
import
java.util.List
;
import
java.util.List
;
...
@@ -29,6 +29,7 @@ public interface FileUtility {
...
@@ -29,6 +29,7 @@ public interface FileUtility {
String
getFileName
(
String
url
);
// get file name from its URL
String
getFileName
(
String
url
);
// get file name from its URL
String
getFileNameWithoutExtension
(
String
url
);
// get file name without extension
String
getFileNameWithoutExtension
(
String
url
);
// get file name without extension
String
getFileExtension
(
String
url
);
// get file extension from URL
String
getFileExtension
(
String
url
);
// get file extension from URL
String
getFileType
(
String
url
);
// get file type from URL
String
getInternalExtension
(
DocumentType
type
);
// get an editor internal extension
String
getInternalExtension
(
DocumentType
type
);
// get an editor internal extension
List
<
String
>
getFileExts
();
// get all the supported file extensions
List
<
String
>
getFileExts
();
// get all the supported file extensions
List
<
String
>
getFillExts
();
// get file extensions that can be filled
List
<
String
>
getFillExts
();
// get file extensions that can be filled
...
...
src/main/java/com/zzsn/knowbase/util/file/Md5Utils.java
0 → 100644
浏览文件 @
f3739005
package
com
.
zzsn
.
knowbase
.
util
.
file
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.binary.Hex
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
/**
* Md5 工具类
* need commons-codec-1.6.jar +
* @author zhangcx
* @date 2019-7-23
*/
@Slf4j
public
class
Md5Utils
{
private
static
MessageDigest
MD5
=
null
;
static
{
try
{
MD5
=
MessageDigest
.
getInstance
(
"MD5"
);
}
catch
(
NoSuchAlgorithmException
ne
)
{
ne
.
printStackTrace
();
}
}
public
static
String
getFileMd5
(
String
filePath
)
{
if
(
StringUtils
.
isBlank
(
filePath
))
{
return
null
;
}
return
getFileMd5
(
new
File
(
filePath
));
}
/**
* 对一个文件获取md5值
*/
public
static
String
getFileMd5
(
File
file
)
{
FileInputStream
fileInputStream
=
null
;
try
{
fileInputStream
=
new
FileInputStream
(
file
);
byte
[]
buffer
=
new
byte
[
8192
];
int
length
;
while
((
length
=
fileInputStream
.
read
(
buffer
))
!=
-
1
)
{
MD5
.
update
(
buffer
,
0
,
length
);
}
return
new
String
(
Hex
.
encodeHex
(
MD5
.
digest
()));
}
catch
(
IOException
e
)
{
log
.
error
(
"$$$ 获取文件md5失败!"
,
e
);
return
null
;
}
finally
{
try
{
if
(
fileInputStream
!=
null
)
{
fileInputStream
.
close
();
}
}
catch
(
IOException
e
)
{
log
.
error
(
"关闭文件流出错!"
,
e
);
}
}
}
/**
* 计算字符串的md5值
* @param target 字符串
* @return md5 value
*/
public
static
String
md5
(
final
String
target
)
{
return
DigestUtils
.
md5Hex
(
target
);
}
}
src/main/resources/application.yml
浏览文件 @
f3739005
...
@@ -50,9 +50,18 @@ know:
...
@@ -50,9 +50,18 @@ know:
checkuserurl
:
http://127.0.0.1:9988/sys/checkToken
checkuserurl
:
http://127.0.0.1:9988/sys/checkToken
getusersurl
:
http://127.0.0.1:9988/sys/user/thirdparty
getusersurl
:
http://127.0.0.1:9988/sys/user/thirdparty
document
:
server
:
host
:
http://gq55rd.natappfree.cc
files
:
files
:
storage
:
E:/aaa
/
storage
:
D:/know
/
docservice
:
docservice
:
url
:
site
:
http://114.116.116.241:80/
converter
:
ConvertService.ashx
command
:
coauthoring/CommandService.ashx
api
:
web-apps/apps/api/documents/api.js
preloader
:
web-apps/apps/api/documents/cache-scripts.html
fillforms-docs
:
.docx|.oform
fillforms-docs
:
.docx|.oform
viewed-docs
:
.djvu|.oxps|.pdf|.xps
viewed-docs
:
.djvu|.oxps|.pdf|.xps
edited-docs
:
.csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx
edited-docs
:
.csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx
...
...
src/test/java/com/zzsn/knowbase/KnowBaseApplicationTests.java
浏览文件 @
f3739005
...
@@ -22,10 +22,10 @@ class KnowBaseApplicationTests {
...
@@ -22,10 +22,10 @@ class KnowBaseApplicationTests {
@Test
@Test
void
contextLoads
()
throws
IOException
{
void
contextLoads
()
throws
IOException
{
ResponseEntity
<
Resource
>
re
=
localFileService
.
download
(
"abc.docx"
,
"E:/aaa/abc.docx"
);
//
ResponseEntity<Resource> re = localFileService.download("abc.docx", "E:/aaa/abc.docx");
File
file
=
re
.
getBody
().
getFile
();
//
File file = re.getBody().getFile();
//
System
.
out
.
println
(
re
);
//
System.out.println(re);
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论