Compare commits

...

5 Commits
3.2.4 ... 3.2.6

Author SHA1 Message Date
zhaojun
082bb07213 fix: 修复 webdav 账号密码错误问题 2022-06-16 20:11:54 +08:00
zhaojun
803b8cdf71 🔖 发布 3.2.5 版本 2022-05-16 21:41:59 +08:00
zhaojun
eca5f7e48b feature: 新增挂载 webdav client pom 依赖 2022-05-16 21:41:36 +08:00
zhaojun
b70c37f3f0 feature: 新增挂载 webdav 功能 2022-05-16 21:40:58 +08:00
zhaojun
5cb2844141 🐛 修复错误的 content_disposition 和 contentType 导致下载文件格式被浏览器识别错误 2022-05-16 20:50:49 +08:00
8 changed files with 164 additions and 8 deletions

10
pom.xml
View File

@@ -12,7 +12,7 @@
<groupId>im.zhaojun</groupId>
<artifactId>zfile</artifactId>
<version>3.2.3</version>
<version>3.2.5</version>
<name>zfile</name>
<packaging>war</packaging>
<description>一个在线的文件浏览系统</description>
@@ -111,6 +111,14 @@
</exclusions>
</dependency>
<!-- webdav client -->
<dependency>
<groupId>com.github.lookfirst</groupId>
<artifactId>sardine</artifactId>
<version>5.10</version>
</dependency>
<!-- 其他工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>

View File

@@ -23,6 +23,12 @@ public class StorageConfigConstant {
public static final String PASSWORD_KEY = "password";
public static final String WEBDAV_USERNAME = "webdavUsername";
public static final String WEBDAV_PASSWORD = "webdavPassword";
public static final String WEBDAV_URL = "webdavUrl";
public static final String HOST_KEY = "host";
public static final String PORT_KEY = "port";

View File

@@ -50,4 +50,10 @@ public class StorageStrategyConfig {
private String region;
private String webdavUsername;
private String webdavPassword;
private String webdavUrl;
}

View File

@@ -17,6 +17,7 @@ public enum StorageTypeEnum {
LOCAL("local", "本地存储"),
ALIYUN("aliyun", "阿里云 OSS"),
TENCENT("tencent", "腾讯云 COS"),
WebDAV("webdav", "WebDAV"),
UPYUN("upyun", "又拍云 USS"),
FTP("ftp", "FTP"),
UFILE("ufile", "UFile"),

View File

@@ -0,0 +1,133 @@
package im.zhaojun.zfile.service.impl;
import cn.hutool.core.util.StrUtil;
import com.github.sardine.DavResource;
import com.github.sardine.Sardine;
import com.github.sardine.SardineFactory;
import im.zhaojun.zfile.exception.NotExistFileException;
import im.zhaojun.zfile.model.constant.StorageConfigConstant;
import im.zhaojun.zfile.model.dto.FileItemDTO;
import im.zhaojun.zfile.model.entity.StorageConfig;
import im.zhaojun.zfile.model.enums.FileTypeEnum;
import im.zhaojun.zfile.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.service.StorageConfigService;
import im.zhaojun.zfile.service.base.AbstractBaseFileService;
import im.zhaojun.zfile.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author zhaojun
*/
@Service
@Slf4j
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class WebdavServiceImpl extends AbstractBaseFileService {
private Sardine sardine;
private String url;
@Resource
private StorageConfigService storageConfigService;
@Override
public void init(Integer driveId) {
this.driveId = driveId;
Map<String, StorageConfig> stringStorageConfigMap =
storageConfigService.selectStorageConfigMapByDriveId(driveId);
this.mergeStrategyConfig(stringStorageConfigMap);
String username = stringStorageConfigMap.get(StorageConfigConstant.WEBDAV_USERNAME).getValue();
String password = stringStorageConfigMap.get(StorageConfigConstant.WEBDAV_PASSWORD).getValue();
url = stringStorageConfigMap.get(StorageConfigConstant.WEBDAV_URL).getValue();
if (Objects.isNull(url)) {
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
isInitialized = false;
} else {
// 如果用户名和密码为空,则使用默认用户名和密码
if (StrUtil.isNotEmpty(username) && StrUtil.isNotEmpty(password)) {
sardine = SardineFactory.begin(username, password);
} else {
sardine = SardineFactory.begin();
}
testConnection();
isInitialized = true;
}
}
@Override
public List<FileItemDTO> fileList(String path) throws Exception {
List<FileItemDTO> resultList = new ArrayList<>();
String requestPath = StringUtils.removeDuplicateSeparator(url + "/" + path);
List<DavResource> resources = sardine.list(requestPath);
Integer index = 0;
for (DavResource res : resources) {
// 如果不是根目录, 则跳过第一个, 因为第一个是当前目录
if (!StrUtil.equals(path, "/") && index++ == 0) {
continue;
}
FileItemDTO fileItemResult = new FileItemDTO();
fileItemResult.setName(res.getName());
fileItemResult.setTime(res.getModified());
fileItemResult.setSize(res.getContentLength());
fileItemResult.setType(res.isDirectory() ? FileTypeEnum.FOLDER : FileTypeEnum.FILE);
fileItemResult.setPath(path);
fileItemResult.setUrl(getDownloadUrl(path + res.getName()));
resultList.add(fileItemResult);
}
return resultList;
}
@Override
public String getDownloadUrl(String path) {
return StringUtils.concatPath(url, path);
}
@Override
public StorageTypeEnum getStorageTypeEnum() {
return StorageTypeEnum.WebDAV;
}
@Override
public List<StorageConfig> storageStrategyConfigList() {
return new ArrayList<StorageConfig>() {{
add(new StorageConfig("webdavUsername", "用户名"));
add(new StorageConfig("webdavPassword", "密码"));
add(new StorageConfig("webdavUrl", "WebDav 链接"));
}};
}
@Override
public FileItemDTO getFileItem(String path) {
List<FileItemDTO> list;
try {
int end = path.lastIndexOf("/");
list = fileList(path.substring(0, end + 1));
} catch (Exception e) {
throw new NotExistFileException();
}
for (FileItemDTO fileItemDTO : list) {
String fullPath = StringUtils.concatUrl(fileItemDTO.getPath(), fileItemDTO.getName());
if (Objects.equals(fullPath, path)) {
return fileItemDTO;
}
}
throw new NotExistFileException();
}
}

View File

@@ -137,16 +137,18 @@ public class FileUtil {
long contentLength = endByte - startByte + 1;
//文件类型
String contentType = request.getServletContext().getMimeType(fileName);
if (Objects.equals(type, LocalFileResponseTypeConstant.DOWNLOAD) || StrUtil.isEmpty(contentType)) {
contentType = "attachment";
if (StrUtil.isEmpty(contentType)) {
contentType = "application/octet-stream";
}
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
response.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
// 这里文件名换你想要的inline 表示浏览器可以直接使用
// 参考资料https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentType + ";filename=" + URLUtil.encode(fileName));
if (Objects.equals(type, LocalFileResponseTypeConstant.DOWNLOAD) || StrUtil.isEmpty(contentType)) {
String contentDisposition = "attachment;filename=" + URLUtil.encode(fileName);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
}
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
// [要下载的开始位置]-[结束位置]/[文件总大小]
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + startByte + rangeSeparator + endByte + "/" + file.length());
@@ -193,4 +195,4 @@ public class FileUtil {
}
}
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long