Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
E
EncryptedFileSystem
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
zhangshuang
EncryptedFileSystem
Commits
376b9355
提交
376b9355
authored
3月 24, 2020
作者:
zhangshuang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
swagger和断点续传
上级
466a9771
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
334 行增加
和
6 行删除
+334
-6
pom.xml
efs-ftp/pom.xml
+7
-0
FtpApplication.java
efs-ftp/src/main/java/com/zjty/efs/ftp/FtpApplication.java
+7
-0
FileDownLoadController.java
...a/com/zjty/efs/ftp/controller/FileDownLoadController.java
+15
-1
FileUploadController.java
...ava/com/zjty/efs/ftp/controller/FileUploadController.java
+75
-3
FileUploadService.java
...main/java/com/zjty/efs/ftp/service/FileUploadService.java
+25
-0
FileDownLoadServiceImpl.java
...om/zjty/efs/ftp/service/impl/FileDownLoadServiceImpl.java
+97
-1
FileUploadServiceImpl.java
.../com/zjty/efs/ftp/service/impl/FileUploadServiceImpl.java
+108
-1
没有找到文件。
efs-ftp/pom.xml
浏览文件 @
376b9355
...
...
@@ -17,6 +17,13 @@
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
</dependency>
<dependency>
<groupId>
com.zjty
</groupId>
<artifactId>
efs-misc
</artifactId>
<version>
1.0-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
...
...
efs-ftp/src/main/java/com/zjty/efs/ftp/FtpApplication.java
浏览文件 @
376b9355
...
...
@@ -2,8 +2,15 @@ package com.zjty.efs.ftp;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.context.annotation.ComponentScan
;
import
springfox.documentation.swagger2.annotations.EnableSwagger2
;
@SpringBootApplication
@ComponentScan
(
basePackages
=
{
"com.zjty.efs.misc"
,
"com.zjty.efs.ftp"
})
@EnableSwagger2
public
class
FtpApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
FtpApplication
.
class
,
args
);
...
...
efs-ftp/src/main/java/com/zjty/efs/ftp/controller/FileDownLoadController.java
浏览文件 @
376b9355
package
com
.
zjty
.
efs
.
ftp
.
controller
;
import
com.zjty.efs.ftp.service.FileDownLoadService
;
import
com.zjty.efs.misc.config.AutoDocument
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
...
...
@@ -10,13 +15,22 @@ import org.springframework.web.bind.annotation.RestController;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
@AutoDocument
@RestController
@RequestMapping
(
"/file"
)
@Api
(
tags
=
"文件下载"
,
description
=
"文件下载"
)
public
class
FileDownLoadController
{
@Autowired
private
FileDownLoadService
fileDownLoadService
;
@GetMapping
(
"/downLoad/{fileName}"
)
@GetMapping
(
"/download/{fileName}"
)
@ApiOperation
(
value
=
"文件下载"
,
notes
=
"通过文件名称下载文件"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"fileName"
,
value
=
"文件名称"
,
paramType
=
"String"
,
example
=
"1.zip"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"response"
,
value
=
"响应对象"
,
paramType
=
"HttpServletResponse"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"request"
,
value
=
"请求对象"
,
paramType
=
"HttpServletRequest"
,
required
=
true
),
})
public
void
fileDownLoad
(
@PathVariable
(
"fileName"
)
String
fileName
,
HttpServletResponse
response
,
HttpServletRequest
request
){
fileDownLoadService
.
fileDownLoad
(
fileName
,
response
,
request
);
}
...
...
efs-ftp/src/main/java/com/zjty/efs/ftp/controller/FileUploadController.java
浏览文件 @
376b9355
...
...
@@ -2,15 +2,21 @@ package com.zjty.efs.ftp.controller;
import
com.zjty.efs.ftp.base.response.ServerResponse
;
import
com.zjty.efs.ftp.service.FileUploadService
;
import
com.zjty.efs.misc.config.AutoDocument
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PutMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
@AutoDocument
@RestController
@RequestMapping
(
"/file"
)
@Api
(
tags
=
"文件上传"
,
description
=
"文件上传"
)
public
class
FileUploadController
{
@Autowired
...
...
@@ -22,4 +28,70 @@ public class FileUploadController {
return
fileUploadService
.
fileUpload
(
httpServletRequest
);
}
/**
* @author zs
* 检查文件存在与否
*/
@PostMapping
(
"/checkFile"
)
@ResponseBody
@ApiOperation
(
value
=
"文件检查"
,
notes
=
"检查文件存在与否"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"md5File"
,
value
=
"md5生成的文件名称"
,
paramType
=
"String"
,
required
=
true
)
})
public
ServerResponse
checkFile
(
@RequestParam
(
value
=
"md5File"
)
String
md5File
)
{
return
fileUploadService
.
checkFile
(
md5File
);
}
/**
* @author zs
* 检查分片存不存在
*/
@PostMapping
(
"/checkChunk"
)
@ResponseBody
@ApiOperation
(
value
=
"分片检查"
,
notes
=
"检查分片存不存在"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"md5File"
,
value
=
"md5生成的文件名称"
,
paramType
=
"String"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"chunk"
,
value
=
"分片名称"
,
paramType
=
"Integer"
,
required
=
true
)
})
public
ServerResponse
checkChunk
(
@RequestParam
(
value
=
"md5File"
)
String
md5File
,
@RequestParam
(
value
=
"chunk"
)
Integer
chunk
)
{
return
fileUploadService
.
checkChunk
(
md5File
,
chunk
);
}
/**
* @author zs
* 修改上传
*/
@PostMapping
(
"/upload"
)
@ResponseBody
@ApiOperation
(
value
=
"文件上传"
,
notes
=
"上传文件,支持断点续传"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"md5File"
,
value
=
"md5生成的文件名称"
,
paramType
=
"String"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"chunk"
,
value
=
"分片名称"
,
paramType
=
"Integer"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"file"
,
value
=
"文件"
,
paramType
=
"MultipartFile"
,
required
=
true
)
})
public
ServerResponse
upload
(
@RequestParam
(
value
=
"file"
)
MultipartFile
file
,
@RequestParam
(
value
=
"md5File"
)
String
md5File
,
@RequestParam
(
value
=
"chunk"
,
required
=
false
)
Integer
chunk
)
{
//第几片,从0开始
return
fileUploadService
.
upload
(
file
,
md5File
,
chunk
);
}
/**
* @author zs
* 合成分片
*/
@PostMapping
(
"/merge"
)
@ResponseBody
@ApiOperation
(
value
=
"合成分片"
,
notes
=
"合成所有分片"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"md5File"
,
value
=
"md5生成的文件名称"
,
paramType
=
"String"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"chunk"
,
value
=
"最后的分片名称"
,
paramType
=
"Integer"
,
required
=
true
),
@ApiImplicitParam
(
name
=
"file"
,
value
=
"文件"
,
paramType
=
"MultipartFile"
,
required
=
true
)
})
public
ServerResponse
merge
(
@RequestParam
(
value
=
"chunks"
,
required
=
false
)
Integer
chunks
,
@RequestParam
(
value
=
"md5File"
)
String
md5File
,
@RequestParam
(
value
=
"name"
)
String
name
){
return
fileUploadService
.
merge
(
chunks
,
md5File
,
name
);
}
}
efs-ftp/src/main/java/com/zjty/efs/ftp/service/FileUploadService.java
浏览文件 @
376b9355
...
...
@@ -2,6 +2,7 @@ package com.zjty.efs.ftp.service;
import
com.zjty.efs.ftp.base.response.ServerResponse
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
...
...
@@ -14,4 +15,28 @@ public interface FileUploadService {
*/
ServerResponse
fileUpload
(
HttpServletRequest
request
);
/**
* @author zs
* 检查文件存在与否
*/
ServerResponse
checkFile
(
String
md5File
);
/**
* @author zs
* 检查分片存不存在
*/
ServerResponse
checkChunk
(
String
md5File
,
Integer
chunk
);
/**
* @author zs
* 修改上传
*/
ServerResponse
upload
(
MultipartFile
file
,
String
md5File
,
Integer
chunk
);
/**
* @author zs
* 合成分片
*/
ServerResponse
merge
(
Integer
chunks
,
String
md5File
,
String
name
);
}
efs-ftp/src/main/java/com/zjty/efs/ftp/service/impl/FileDownLoadServiceImpl.java
浏览文件 @
376b9355
...
...
@@ -2,12 +2,16 @@ package com.zjty.efs.ftp.service.impl;
import
com.zjty.efs.ftp.service.FileDownLoadService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.catalina.connector.ClientAbortException
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.*
;
import
java.net.URLEncoder
;
import
static
javax
.
xml
.
transform
.
OutputKeys
.
ENCODING
;
@Service
@Slf4j
...
...
@@ -16,7 +20,16 @@ public class FileDownLoadServiceImpl implements FileDownLoadService {
@Value
(
"${file.address}"
)
private
String
fileAddress
;
@Override
/**
* 下载服务器已存在的文件
*
* @param httpServletRequest
* 请求对象
* @param response
* 响应对象
* @param fileName
* 文件名称(绝对)
*/
public
void
fileDownLoad
(
String
fileName
,
HttpServletResponse
response
,
HttpServletRequest
httpServletRequest
)
{
if
(
fileName
!=
null
){
response
.
setHeader
(
"content-type"
,
"application/octet-stream"
);
...
...
@@ -67,6 +80,89 @@ public class FileDownLoadServiceImpl implements FileDownLoadService {
}
}
/**
* 下载服务器已存在的文件
*
* @param request
* 请求对象
* @param response
* 响应对象
* @param fileName
* 文件名称(绝对)
*/
public
void
download
(
String
fileName
,
HttpServletResponse
response
,
HttpServletRequest
request
)
{
File
proposeFile
=
new
File
(
fileAddress
+
"/"
+
fileName
);
log
.
info
(
"下载文件路径:"
+
proposeFile
.
getPath
());
setFileDownloadHeader
(
request
,
response
,
fileName
);
InputStream
inputStream
=
null
;
OutputStream
bufferOut
=
null
;
try
{
// 设置响应报头
long
fSize
=
proposeFile
.
length
();
response
.
setContentType
(
request
.
getServletContext
().
getMimeType
(
fileName
));
// Content-Disposition: attachment; filename=WebGoat-OWASP_Developer-5.2.zip
response
.
setHeader
(
"Content-Disposition"
,
"attachment;filename="
+
new
String
(
fileName
.
getBytes
(
"utf-8"
),
"utf-8"
));
// Accept-Ranges: bytes
response
.
setHeader
(
"Accept-Ranges"
,
"bytes"
);
long
pos
=
0
,
last
=
fSize
-
1
,
sum
=
0
;
//pos开始读取位置; last最后读取位置; sum记录总共已经读取了多少字节
if
(
null
!=
request
.
getHeader
(
"Range"
))
{
// 断点续传
response
.
setStatus
(
HttpServletResponse
.
SC_PARTIAL_CONTENT
);
try
{
// 情景一:RANGE: bytes=2000070- 情景二:RANGE: bytes=2000070-2000970
String
numRang
=
request
.
getHeader
(
"Range"
).
replaceAll
(
"bytes="
,
""
);
String
[]
strRange
=
numRang
.
split
(
"-"
);
if
(
strRange
.
length
==
2
)
{
pos
=
Long
.
parseLong
(
strRange
[
0
].
trim
());
last
=
Long
.
parseLong
(
strRange
[
1
].
trim
());
}
else
{
pos
=
Long
.
parseLong
(
numRang
.
replaceAll
(
"-"
,
""
).
trim
());
}
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
request
.
getHeader
(
"Range"
)
+
" is not Number!"
);
pos
=
0
;
}
}
long
rangLength
=
last
-
pos
+
1
;
// 总共需要读取的字节
// Content-Range: bytes 10-1033/304974592
String
contentRange
=
new
StringBuffer
(
"bytes "
).
append
(
pos
).
append
(
"-"
).
append
(
last
).
append
(
"/"
).
append
(
fSize
).
toString
();
response
.
setHeader
(
"Content-Range"
,
contentRange
);
// Content-Length: 1024
response
.
addHeader
(
"Content-Length"
,
String
.
valueOf
(
rangLength
));
// 跳过已经下载的部分,进行后续下载
bufferOut
=
new
BufferedOutputStream
(
response
.
getOutputStream
());
inputStream
=
new
BufferedInputStream
(
new
FileInputStream
(
proposeFile
));
inputStream
.
skip
(
pos
);
byte
[]
buffer
=
new
byte
[
1024
];
int
length
=
0
;
while
(
sum
<
rangLength
)
{
length
=
inputStream
.
read
(
buffer
,
0
,
((
rangLength
-
sum
)
<=
buffer
.
length
?
((
int
)
(
rangLength
-
sum
))
:
buffer
.
length
));
sum
=
sum
+
length
;
bufferOut
.
write
(
buffer
,
0
,
length
);
}
}
catch
(
Throwable
e
)
{
if
(
e
instanceof
ClientAbortException
)
{
// 浏览器点击取消
log
.
info
(
"用户取消下载!"
);
}
else
{
log
.
error
(
"下载文件失败...."
);
e
.
printStackTrace
();
}
}
finally
{
try
{
if
(
bufferOut
!=
null
)
{
bufferOut
.
close
();
}
if
(
inputStream
!=
null
)
{
inputStream
.
close
();
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
/**
* 解决中文名称
* @param request
...
...
efs-ftp/src/main/java/com/zjty/efs/ftp/service/impl/FileUploadServiceImpl.java
浏览文件 @
376b9355
...
...
@@ -76,9 +76,116 @@ public class FileUploadServiceImpl implements FileUploadService {
}
}
}
else
{
log
.
info
(
"上传失败,请重新确定key值,重新上传"
);
log
.
error
(
"上传失败,请重新确定key值,重新上传"
);
return
ServerResponse
.
error
(
"上传失败,请重新确定key值,重新上传"
);
}
return
ServerResponse
.
success
(
fileReturns
);
}
@Override
public
ServerResponse
checkFile
(
String
md5File
)
{
Boolean
exist
=
false
;
//实际项目中,这个md5File唯一值,应该保存到数据库或者缓存中,通过判断唯一值存不存在,来判断文件存不存在,这里我就不演示了
/*if(true) {
exist = true;
}*/
return
ServerResponse
.
success
(
exist
);
}
@Override
public
ServerResponse
checkChunk
(
String
md5File
,
Integer
chunk
)
{
Boolean
exist
=
false
;
//String path = "D:/webuploader/"+md5File+"/";
String
chunkPath
=
fileAddress
+
"/"
+
md5File
+
"/"
;
//分片存放目录
String
chunkName
=
chunk
+
".tmp"
;
//分片名
File
file
=
new
File
(
chunkPath
+
chunkName
);
if
(
file
.
exists
())
{
exist
=
true
;
}
return
ServerResponse
.
success
(
exist
);
}
@Override
public
ServerResponse
upload
(
MultipartFile
file
,
String
md5File
,
Integer
chunk
)
{
//String path = "D:/webuploader/"+md5File+"/";
String
chunkPath
=
fileAddress
+
"/"
+
md5File
+
"/"
;
//分片存放目录
File
dirFile
=
new
File
(
chunkPath
);
if
(!
dirFile
.
exists
())
{
//目录不存在,创建目录
dirFile
.
mkdirs
();
}
String
chunkName
;
if
(
chunk
==
null
)
{
//表示是小文件,还没有一片
chunkName
=
"0.tmp"
;
}
else
{
chunkName
=
chunk
+
".tmp"
;
}
String
filePath
=
chunkPath
+
chunkName
;
File
saveFile
=
new
File
(
filePath
);
try
{
if
(!
saveFile
.
exists
())
{
saveFile
.
createNewFile
();
//文件不存在,则创建
}
file
.
transferTo
(
saveFile
);
//将文件保存
}
catch
(
IOException
e
)
{
return
ServerResponse
.
error
(
"false"
);
}
return
ServerResponse
.
success
(
"true"
);
}
@Override
public
ServerResponse
merge
(
Integer
chunks
,
String
md5File
,
String
name
)
{
FileOutputStream
fileOutputStream
=
null
;
//合成后的文件
try
{
fileOutputStream
=
new
FileOutputStream
(
fileAddress
+
"/"
+
name
);
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
try
{
byte
[]
buf
=
new
byte
[
1024
];
for
(
long
i
=
0
;
i
<
chunks
;
i
++)
{
String
chunkFile
=
i
+
".tmp"
;
File
file
=
new
File
(
fileAddress
+
"/"
+
md5File
+
"/"
+
chunkFile
);
InputStream
inputStream
=
new
FileInputStream
(
file
);
int
len
=
0
;
while
((
len
=
inputStream
.
read
(
buf
))
!=
-
1
){
fileOutputStream
.
write
(
buf
,
0
,
len
);
}
inputStream
.
close
();
}
//删除md5目录,及临时文件
deleteFile
(
new
File
(
fileAddress
+
"/"
+
md5File
));
}
catch
(
Exception
e
)
{
return
ServerResponse
.
error
(
"false"
);
}
finally
{
try
{
fileOutputStream
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
return
ServerResponse
.
success
(
"true"
);
}
public
static
void
deleteFile
(
File
file
){
//判断文件不为null或文件目录存在
if
(
file
==
null
||
!
file
.
exists
()){
System
.
out
.
println
(
"文件删除失败,请检查文件路径是否正确"
);
return
;
}
//取得这个目录下的所有子文件对象
File
[]
files
=
file
.
listFiles
();
//遍历该目录下的文件对象
for
(
File
f:
files
){
//打印文件名
//判断子目录是否存在子目录,如果是文件则删除
if
(
f
.
isDirectory
()){
deleteFile
(
f
);
}
else
{
f
.
delete
();
}
}
//删除空文件夹 for循环已经把上一层节点的目录清空。
file
.
delete
();
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论