file-online-preview/server/src/main/java/cn/keking/utils/DownloadUtils.java

169 lines
7.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.mola.galimatias.GalimatiasParseException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;
import static cn.keking.utils.KkFileUtils.isFtpUrl;
import static cn.keking.utils.KkFileUtils.isHttpUrl;
/**
* @author yudian-it
*/
public class DownloadUtils {
private final static Logger logger = LoggerFactory.getLogger(DownloadUtils.class);
private static final String fileDir = ConfigConstants.getFileDir();
private static final String URL_PARAM_FTP_USERNAME = "ftp.username";
private static final String URL_PARAM_FTP_PASSWORD = "ftp.password";
private static final String URL_PARAM_FTP_CONTROL_ENCODING = "ftp.control.encoding";
private static final RestTemplate restTemplate = new RestTemplate();
private static final ObjectMapper mapper = new ObjectMapper();
/**
* @param fileAttribute fileAttribute
* @param fileName 文件名
* @return 本地文件绝对路径
*/
public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
// 忽略ssl证书
String urlStr = null;
try {
SslUtils.ignoreSsl();
urlStr = fileAttribute.getUrl().replaceAll("\\+", "%20").replaceAll(" ", "%20");
} catch (Exception e) {
logger.error("忽略SSL证书异常:", e);
}
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
String realPath = getRelFilePath(fileName, fileAttribute);
// 判断是否非法地址
if (KkFileUtils.isIllegalFileName(realPath)) {
response.setCode(1);
response.setContent(null);
response.setMsg("下载失败:文件名不合法!" + urlStr);
return response;
}
if (!KkFileUtils.isAllowedUpload(realPath)) {
response.setCode(1);
response.setContent(null);
response.setMsg("下载失败:不支持的类型!" + urlStr);
return response;
}
if (fileAttribute.isCompressFile()) { //压缩包文件 直接赋予路径 不予下载
response.setContent(fileDir + fileName);
response.setMsg(fileName);
return response;
}
// 如果文件是否已经存在、且不强制更新,则直接返回文件路径
if (KkFileUtils.isExist(realPath) && !fileAttribute.forceUpdatedCache()) {
response.setContent(realPath);
response.setMsg(fileName);
return response;
}
try {
URL url = WebUtils.normalizedURL(urlStr);
if (!fileAttribute.getSkipDownLoad()) {
if (isHttpUrl(url)) {
File realFile = new File(realPath);
SimpleClientHttpRequestFactory httpFactory = new SimpleClientHttpRequestFactory();
//连接超时10秒默认无限制单位毫秒
httpFactory.setConnectTimeout(60 * 1000);
//读取超时5秒,默认无限限制,单位:毫秒
httpFactory.setReadTimeout(60 * 1000);
restTemplate.setRequestFactory(httpFactory);
RequestCallback requestCallback = request -> {
request.getHeaders().setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
String proxyAuthorization = fileAttribute.getKkProxyAuthorization();
if(StringUtils.hasText(proxyAuthorization)){
Map<String,String> proxyAuthorizationMap = mapper.readValue(proxyAuthorization, Map.class);
proxyAuthorizationMap.forEach((key, value) -> request.getHeaders().set(key, value));
}
};
try {
restTemplate.execute(url.toURI(), HttpMethod.GET, requestCallback, fileResponse -> {
FileUtils.copyToFile(fileResponse.getBody(), realFile);
return null;
});
} catch (Exception e) {
response.setCode(1);
response.setContent(null);
response.setMsg("下载失败:" + e);
return response;
}
} else if (isFtpUrl(url)) {
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.setMsg("url不能识别url" + urlStr);
}
}
response.setContent(realPath);
response.setMsg(fileName);
return response;
} catch (IOException | GalimatiasParseException e) {
logger.error("文件下载失败url{}", urlStr);
response.setCode(1);
response.setContent(null);
if (e instanceof FileNotFoundException) {
response.setMsg("文件不存在!!!");
} else {
response.setMsg(e.getMessage());
}
return response;
}
}
/**
* 获取真实文件绝对路径
*
* @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);
}
String realPath = fileDir + fileName;
File dirFile = new File(fileDir);
if (!dirFile.exists() && !dirFile.mkdirs()) {
logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
}
return realPath;
}
}