Commit 37762cf0 authored by 陈精华's avatar 陈精华 Committed by kl

支持FTP文件地址作为预览源url

parent a78f1e5f
...@@ -147,6 +147,12 @@ ...@@ -147,6 +147,12 @@
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>1.2</version> <version>1.2</version>
</dependency> </dependency>
<!-- FTP -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency> <dependency>
<groupId>com.thoughtworks.xstream</groupId> <groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId> <artifactId>xstream</artifactId>
......
...@@ -39,3 +39,10 @@ cache.clean = true ...@@ -39,3 +39,10 @@ cache.clean = true
#converted.file.charset = GBK #converted.file.charset = GBK
#office类型文档(word ppt)样式,默认为图片(image),可配置为pdf(预览时也有按钮切换) #office类型文档(word ppt)样式,默认为图片(image),可配置为pdf(预览时也有按钮切换)
#office.preview.type = pdf #office.preview.type = pdf
#预览源为FTP时 FTP用户名,可在ftp url后面加参数ftp.username=ftpuser指定,不指定默认用配置的
ftp.username = ftpuser
#预览源为FTP时 FTP密码,可在ftp url后面加参数ftp.password=123456指定,不指定默认用配置的
ftp.password = 123456
#预览源为FTP时, FTP连接默认ControlEncoding(根据FTP服务器操作系统选择,Linux一般为UTF-8,Windows一般为GBK),可在ftp url后面加参数ftp.control.encoding=UTF-8指定,不指定默认用配置的
ftp.control.encoding = UTF-8
...@@ -18,6 +18,9 @@ public class ConfigConstants { ...@@ -18,6 +18,9 @@ public class ConfigConstants {
private static String[] media = {}; private static String[] media = {};
private static String convertedFileCharset; private static String convertedFileCharset;
private static String officePreviewType; private static String officePreviewType;
private static String ftpUsername;
private static String ftpPassword;
private static String ftpControlEncoding;
private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator; private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator;
public static String[] getSimText() { public static String[] getSimText() {
...@@ -52,6 +55,30 @@ public class ConfigConstants { ...@@ -52,6 +55,30 @@ public class ConfigConstants {
ConfigConstants.officePreviewType = officePreviewType; ConfigConstants.officePreviewType = officePreviewType;
} }
public static String getFtpUsername() {
return ftpUsername;
}
public static void setFtpUsername(String ftpUsername) {
ConfigConstants.ftpUsername = ftpUsername;
}
public static String getFtpPassword() {
return ftpPassword;
}
public static String getFtpControlEncoding() {
return ftpControlEncoding;
}
public static void setFtpControlEncoding(String ftpControlEncoding) {
ConfigConstants.ftpControlEncoding = ftpControlEncoding;
}
public static void setFtpPassword(String ftpPassword) {
ConfigConstants.ftpPassword = ftpPassword;
}
public static String getFileDir() { public static String getFileDir() {
return fileDir; return fileDir;
} }
......
...@@ -24,6 +24,10 @@ public class ConfigRefreshComponent { ...@@ -24,6 +24,10 @@ public class ConfigRefreshComponent {
public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql"; public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql";
public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv"; public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv";
public static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding");
public static final String DEFAULT_FTP_USERNAME = null;
public static final String DEFAULT_FTP_PASSWORD = null;
public static final String DEFAULT_FTP_CONTROL_ENCODING = "UTF-8";
@PostConstruct @PostConstruct
...@@ -37,13 +41,15 @@ public class ConfigRefreshComponent { ...@@ -37,13 +41,15 @@ public class ConfigRefreshComponent {
public void run() { public void run() {
try { try {
Properties properties = new Properties(); Properties properties = new Properties();
Properties sysProperties = System.getProperties();
String text; String text;
String media; String media;
String convertedFileCharset = sysProperties.getProperty("sun.jnu.encoding");
String[] textArray; String[] textArray;
String[] mediaArray; String[] mediaArray;
String convertedFileCharset;
String officePreviewType; String officePreviewType;
String ftpUsername;
String ftpPassword;
String ftpControlEncoding;
String configFilePath = OfficeUtils.getCustomizedConfigPath(); String configFilePath = OfficeUtils.getCustomizedConfigPath();
while (true) { while (true) {
FileReader fileReader = new FileReader(configFilePath); FileReader fileReader = new FileReader(configFilePath);
...@@ -51,20 +57,26 @@ public class ConfigRefreshComponent { ...@@ -51,20 +57,26 @@ public class ConfigRefreshComponent {
properties.load(bufferedReader); properties.load(bufferedReader);
text = properties.getProperty("simText", DEFAULT_TXT_TYPE); text = properties.getProperty("simText", DEFAULT_TXT_TYPE);
media = properties.getProperty("media", DEFAULT_MEDIA_TYPE); media = properties.getProperty("media", DEFAULT_MEDIA_TYPE);
convertedFileCharset = properties.getProperty("converted.file.charset", convertedFileCharset); convertedFileCharset = properties.getProperty("converted.file.charset", DEFAULT_CONVERTER_CHARSET);
officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE); officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE);
ftpUsername = properties.getProperty("ftp.username", DEFAULT_FTP_USERNAME);
ftpPassword = properties.getProperty("ftp.password", DEFAULT_FTP_PASSWORD);
ftpControlEncoding = properties.getProperty("ftp.control.encoding", DEFAULT_FTP_CONTROL_ENCODING);
textArray = text.split(","); textArray = text.split(",");
mediaArray = media.split(","); mediaArray = media.split(",");
ConfigConstants.setSimText(textArray); ConfigConstants.setSimText(textArray);
ConfigConstants.setMedia(mediaArray); ConfigConstants.setMedia(mediaArray);
ConfigConstants.setConvertedFileCharset(convertedFileCharset); ConfigConstants.setConvertedFileCharset(convertedFileCharset);
ConfigConstants.setOfficePreviewType(officePreviewType); ConfigConstants.setOfficePreviewType(officePreviewType);
ConfigConstants.setFtpUsername(ftpUsername);
ConfigConstants.setFtpPassword(ftpPassword);
ConfigConstants.setFtpControlEncoding(ftpControlEncoding);
bufferedReader.close(); bufferedReader.close();
fileReader.close(); fileReader.close();
Thread.sleep(1000L); Thread.sleep(1000L);
} }
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
LOGGER.error("读取配置文件异常:{}", e); LOGGER.error("读取配置文件异常", e);
} }
} }
} }
......
...@@ -30,12 +30,11 @@ public class CompressFilePreviewImpl implements FilePreview{ ...@@ -30,12 +30,11 @@ public class CompressFilePreviewImpl implements FilePreview{
@Override @Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String decodedUrl=fileAttribute.getDecodedUrl();
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileTree = null; String fileTree = null;
// 判断文件名是否存在(redis缓存读取) // 判断文件名是否存在(redis缓存读取)
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) { if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName); ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix); model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());
......
...@@ -48,7 +48,6 @@ public class OfficeFilePreviewImpl implements FilePreview { ...@@ -48,7 +48,6 @@ public class OfficeFilePreviewImpl implements FilePreview {
String originUrl = (String) model.asMap().get("originUrl"); String originUrl = (String) model.asMap().get("originUrl");
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String decodedUrl=fileAttribute.getDecodedUrl();
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx"); boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf"); String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
String outFilePath = fileDir + pdfName; String outFilePath = fileDir + pdfName;
...@@ -56,7 +55,7 @@ public class OfficeFilePreviewImpl implements FilePreview { ...@@ -56,7 +55,7 @@ public class OfficeFilePreviewImpl implements FilePreview {
if (!fileUtils.listConvertedFiles().containsKey(pdfName)) { if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
String filePath = fileDir + fileName; String filePath = fileDir + fileName;
if (!new File(filePath).exists()) { if (!new File(filePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null); ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, null);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix); model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());
......
...@@ -35,7 +35,6 @@ public class PdfFilePreviewImpl implements FilePreview{ ...@@ -35,7 +35,6 @@ public class PdfFilePreviewImpl implements FilePreview{
@Override @Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String decodedUrl=fileAttribute.getDecodedUrl();
String suffix=fileAttribute.getSuffix(); String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString(); String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
...@@ -46,7 +45,7 @@ public class PdfFilePreviewImpl implements FilePreview{ ...@@ -46,7 +45,7 @@ public class PdfFilePreviewImpl implements FilePreview{
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) { if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) {
//当文件不存在时,就去下载 //当文件不存在时,就去下载
if (!new File(outFilePath).exists()) { if (!new File(outFilePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName); ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) { if (0 != response.getCode()) {
model.addAttribute("fileType", suffix); model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg()); model.addAttribute("msg", response.getMsg());
......
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
...@@ -13,7 +17,16 @@ import java.util.UUID; ...@@ -13,7 +17,16 @@ import java.util.UUID;
@Component @Component
public class DownloadUtils { public class DownloadUtils {
String fileDir = ConfigConstants.getFileDir(); private static final Logger LOGGER = LoggerFactory.getLogger(DownloadUtils.class);
private String fileDir = ConfigConstants.getFileDir();
@Autowired
private FileUtils fileUtils;
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";
/** /**
* 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解 * 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解
...@@ -21,11 +34,12 @@ public class DownloadUtils { ...@@ -21,11 +34,12 @@ public class DownloadUtils {
* 应该是转义出了问题,url转义中会把+号当成空格来计算,所以才会出现这种情况,遂想要通过整体替换空格为加号,因为url * 应该是转义出了问题,url转义中会把+号当成空格来计算,所以才会出现这种情况,遂想要通过整体替换空格为加号,因为url
* 中的参数部分是不会出现空格的,但是文件名中就不好确定了,所以只对url参数部分做替换 * 中的参数部分是不会出现空格的,但是文件名中就不好确定了,所以只对url参数部分做替换
* 注: 针对URLEncoder.encode(s,charset)会将空格转成+的情况需要做下面的替换工作 * 注: 针对URLEncoder.encode(s,charset)会将空格转成+的情况需要做下面的替换工作
* @param urlAddress * @param fileAttribute
* @param type
* @return * @return
*/ */
public ReturnResponse<String> downLoad(String urlAddress, String type, String fileName) { public ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
String urlAddress = fileAttribute.getDecodedUrl();
String type = fileAttribute.getSuffix();
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", ""); ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
URL url = null; URL url = null;
try { try {
...@@ -49,17 +63,24 @@ public class DownloadUtils { ...@@ -49,17 +63,24 @@ public class DownloadUtils {
dirFile.mkdirs(); dirFile.mkdirs();
} }
try { try {
URLConnection connection = url.openConnection(); if ("ftp".equals(url.getProtocol())) {
InputStream in = connection.getInputStream(); String ftpUsername = fileUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
String ftpPassword = fileUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);
String ftpControlEncoding = fileUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING);
FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding);
} else {
URLConnection connection = url.openConnection();
InputStream in = connection.getInputStream();
FileOutputStream os = new FileOutputStream(realPath); FileOutputStream os = new FileOutputStream(realPath);
byte[] buffer = new byte[4 * 1024]; byte[] buffer = new byte[4 * 1024];
int read; int read;
while ((read = in.read(buffer)) > 0) { while ((read = in.read(buffer)) > 0) {
os.write(buffer, 0, read); os.write(buffer, 0, read);
}
os.close();
in.close();
} }
os.close();
in.close();
response.setContent(realPath); response.setContent(realPath);
// 同样针对类txt文件,如果成功msg包含的是转换后的文件名 // 同样针对类txt文件,如果成功msg包含的是转换后的文件名
response.setMsg(fileName); response.setMsg(fileName);
...@@ -68,15 +89,14 @@ public class DownloadUtils { ...@@ -68,15 +89,14 @@ public class DownloadUtils {
if("txt".equals(type)){ if("txt".equals(type)){
convertTextPlainFileCharsetToUtf8(realPath); convertTextPlainFileCharsetToUtf8(realPath);
} }
return response; return response;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("文件下载失败", e);
response.setCode(1); response.setCode(1);
response.setContent(null); response.setContent(null);
if (e instanceof FileNotFoundException) { if (e instanceof FileNotFoundException) {
response.setMsg("文件不存在!!!"); response.setMsg("文件不存在!!!");
}else { } else {
response.setMsg(e.getMessage()); response.setMsg(e.getMessage());
} }
return response; return response;
......
...@@ -285,9 +285,9 @@ public class FileUtils { ...@@ -285,9 +285,9 @@ public class FileUtils {
* @param name * @param name
* @return * @return
*/ */
private String getUrlParameterReg(String url, String name) { public String getUrlParameterReg(String url, String name) {
Map<String, String> mapRequest = new HashMap(); Map<String, String> mapRequest = new HashMap();
String strUrlParam = TruncateUrlPage(url); String strUrlParam = truncateUrlPage(url);
if (strUrlParam == null) { if (strUrlParam == null) {
return ""; return "";
} }
...@@ -312,7 +312,7 @@ public class FileUtils { ...@@ -312,7 +312,7 @@ public class FileUtils {
* @param strURL url地址 * @param strURL url地址
* @return url请求参数部分 * @return url请求参数部分
*/ */
private static String TruncateUrlPage(String strURL) { private String truncateUrlPage(String strURL) {
String strAllParam = null; String strAllParam = null;
strURL = strURL.trim(); strURL = strURL.trim();
String[] arrSplit = strURL.split("[?]"); String[] arrSplit = strURL.split("[?]");
......
package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
/**
* @auther: chenjh
* @since: 2019/6/18 14:36
*/
public class FtpUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(FtpUtils.class);
public static FTPClient connect(String host, int port, String username, String password, String controlEncoding) throws IOException {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(host, port);
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
ftpClient.login(username, password);
}
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
}
ftpClient.setControlEncoding(controlEncoding);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
return ftpClient;
}
public static void download(String ftpUrl, String localFilePath, String ftpUsername, String ftpPassword, String ftpControlEncoding) throws IOException {
String username = StringUtils.isEmpty(ftpUsername) ? ConfigConstants.getFtpUsername() : ftpUsername;
String password = StringUtils.isEmpty(ftpPassword) ? ConfigConstants.getFtpPassword() : ftpPassword;
String controlEncoding = StringUtils.isEmpty(ftpControlEncoding) ? ConfigConstants.getFtpControlEncoding() : ftpControlEncoding;
URL url = new URL(ftpUrl);
String host = url.getHost();
int port = (url.getPort() == -1) ? url.getDefaultPort() : url.getPort();
String remoteFilePath = url.getPath();
LOGGER.debug("FTP connection url:{}, username:{}, password:{}, controlEncoding:{}, localFilePath:{}", ftpUrl, username, password, controlEncoding, localFilePath);
FTPClient ftpClient = connect(host, port, username, password, controlEncoding);
OutputStream outputStream = new FileOutputStream(localFilePath);
ftpClient.enterLocalPassiveMode();
boolean downloadResult = ftpClient.retrieveFile(new String(remoteFilePath.getBytes(controlEncoding), "ISO-8859-1"), outputStream);
LOGGER.debug("FTP download result {}", downloadResult);
outputStream.flush();
outputStream.close();
ftpClient.logout();
ftpClient.disconnect();
}
}
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse; import cn.keking.model.ReturnResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -12,12 +13,14 @@ import org.springframework.stereotype.Component; ...@@ -12,12 +13,14 @@ import org.springframework.stereotype.Component;
*/ */
@Component @Component
public class SimTextUtil { public class SimTextUtil {
String fileDir = ConfigConstants.getFileDir();
@Autowired @Autowired
DownloadUtils downloadUtils; private FileUtils fileUtils;
@Autowired
private DownloadUtils downloadUtils;
public ReturnResponse<String> readSimText(String url, String fileName){ public ReturnResponse<String> readSimText(String url, String fileName){
ReturnResponse<String> response = downloadUtils.downLoad(url, "txt", fileName); FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
return response; return response;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment