Quellcode durchsuchen

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

陈精华 vor 5 Jahren
Ursprung
Commit
37762cf034

+ 6 - 0
jodconverter-web/pom.xml

@@ -147,6 +147,12 @@
             <artifactId>commons-cli</artifactId>
             <version>1.2</version>
         </dependency>
+        <!-- FTP -->
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+            <version>3.6</version>
+        </dependency>
         <dependency>
             <groupId>com.thoughtworks.xstream</groupId>
             <artifactId>xstream</artifactId>

+ 7 - 0
jodconverter-web/src/main/conf/application.properties

@@ -39,3 +39,10 @@ cache.clean = true
 #converted.file.charset = GBK
 #office类型文档(word ppt)样式,默认为图片(image),可配置为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

+ 27 - 0
jodconverter-web/src/main/java/cn/keking/config/ConfigConstants.java

@@ -18,6 +18,9 @@ public class ConfigConstants {
     private static String[] media = {};
     private static String convertedFileCharset;
     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;
 
     public static String[] getSimText() {
@@ -52,6 +55,30 @@ public class ConfigConstants {
         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() {
         return fileDir;
     }

+ 16 - 4
jodconverter-web/src/main/java/cn/keking/config/ConfigRefreshComponent.java

@@ -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_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
@@ -37,13 +41,15 @@ public class ConfigRefreshComponent {
         public void run() {
             try {
                 Properties properties = new Properties();
-                Properties sysProperties = System.getProperties();
                 String text;
                 String media;
-                String convertedFileCharset = sysProperties.getProperty("sun.jnu.encoding");
                 String[] textArray;
                 String[] mediaArray;
+                String convertedFileCharset;
                 String officePreviewType;
+                String ftpUsername;
+                String ftpPassword;
+                String ftpControlEncoding;
                 String configFilePath = OfficeUtils.getCustomizedConfigPath();
                 while (true) {
                     FileReader fileReader = new FileReader(configFilePath);
@@ -51,20 +57,26 @@ public class ConfigRefreshComponent {
                     properties.load(bufferedReader);
                     text = properties.getProperty("simText", DEFAULT_TXT_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);
+                    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(",");
                     mediaArray = media.split(",");
                     ConfigConstants.setSimText(textArray);
                     ConfigConstants.setMedia(mediaArray);
                     ConfigConstants.setConvertedFileCharset(convertedFileCharset);
                     ConfigConstants.setOfficePreviewType(officePreviewType);
+                    ConfigConstants.setFtpUsername(ftpUsername);
+                    ConfigConstants.setFtpPassword(ftpPassword);
+                    ConfigConstants.setFtpControlEncoding(ftpControlEncoding);
                     bufferedReader.close();
                     fileReader.close();
                     Thread.sleep(1000L);
                 }
             } catch (IOException | InterruptedException e) {
-                LOGGER.error("读取配置文件异常:{}", e);
+                LOGGER.error("读取配置文件异常", e);
             }
         }
     }

+ 1 - 2
jodconverter-web/src/main/java/cn/keking/service/impl/CompressFilePreviewImpl.java

@@ -30,12 +30,11 @@ public class CompressFilePreviewImpl implements FilePreview{
     @Override
     public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
         String fileName=fileAttribute.getName();
-        String decodedUrl=fileAttribute.getDecodedUrl();
         String suffix=fileAttribute.getSuffix();
         String fileTree = null;
         // 判断文件名是否存在(redis缓存读取)
         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()) {
                 model.addAttribute("fileType", suffix);
                 model.addAttribute("msg", response.getMsg());

+ 1 - 2
jodconverter-web/src/main/java/cn/keking/service/impl/OfficeFilePreviewImpl.java

@@ -48,7 +48,6 @@ public class OfficeFilePreviewImpl implements FilePreview {
         String originUrl = (String) model.asMap().get("originUrl");
         String suffix=fileAttribute.getSuffix();
         String fileName=fileAttribute.getName();
-        String decodedUrl=fileAttribute.getDecodedUrl();
         boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
         String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
         String outFilePath = fileDir + pdfName;
@@ -56,7 +55,7 @@ public class OfficeFilePreviewImpl implements FilePreview {
         if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
             String filePath = fileDir + fileName;
             if (!new File(filePath).exists()) {
-                ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null);
+                ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, null);
                 if (0 != response.getCode()) {
                     model.addAttribute("fileType", suffix);
                     model.addAttribute("msg", response.getMsg());

+ 1 - 2
jodconverter-web/src/main/java/cn/keking/service/impl/PdfFilePreviewImpl.java

@@ -35,7 +35,6 @@ public class PdfFilePreviewImpl implements FilePreview{
 
     @Override
     public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
-        String decodedUrl=fileAttribute.getDecodedUrl();
         String suffix=fileAttribute.getSuffix();
         String fileName=fileAttribute.getName();
         String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
@@ -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 (!new File(outFilePath).exists()) {
-                ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName);
+                ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
                 if (0 != response.getCode()) {
                     model.addAttribute("fileType", suffix);
                     model.addAttribute("msg", response.getMsg());

+ 36 - 16
jodconverter-web/src/main/java/cn/keking/utils/DownloadUtils.java

@@ -1,7 +1,11 @@
 package cn.keking.utils;
 
 import cn.keking.config.ConfigConstants;
+import cn.keking.model.FileAttribute;
 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 java.io.*;
 import java.net.*;
@@ -13,7 +17,16 @@ import java.util.UUID;
 @Component
 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 {
      * 应该是转义出了问题,url转义中会把+号当成空格来计算,所以才会出现这种情况,遂想要通过整体替换空格为加号,因为url
      * 中的参数部分是不会出现空格的,但是文件名中就不好确定了,所以只对url参数部分做替换
      * 注: 针对URLEncoder.encode(s,charset)会将空格转成+的情况需要做下面的替换工作
-     * @param urlAddress
-     * @param type
+     * @param fileAttribute
      * @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, "下载成功!!!", "");
         URL url = null;
         try {
@@ -49,17 +63,24 @@ public class DownloadUtils {
             dirFile.mkdirs();
         }
         try {
-            URLConnection connection = url.openConnection();
-            InputStream in = connection.getInputStream();
+            if ("ftp".equals(url.getProtocol())) {
+                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);
-            byte[] buffer = new byte[4 * 1024];
-            int read;
-            while ((read = in.read(buffer)) > 0) {
-                os.write(buffer, 0, read);
+                FileOutputStream os = new FileOutputStream(realPath);
+                byte[] buffer = new byte[4 * 1024];
+                int read;
+                while ((read = in.read(buffer)) > 0) {
+                    os.write(buffer, 0, read);
+                }
+                os.close();
+                in.close();
             }
-            os.close();
-            in.close();
             response.setContent(realPath);
             // 同样针对类txt文件,如果成功msg包含的是转换后的文件名
             response.setMsg(fileName);
@@ -68,15 +89,14 @@ public class DownloadUtils {
             if("txt".equals(type)){
                 convertTextPlainFileCharsetToUtf8(realPath);
             }
-
             return response;
         } catch (IOException e) {
-            e.printStackTrace();
+            LOGGER.error("文件下载失败", e);
             response.setCode(1);
             response.setContent(null);
             if (e instanceof FileNotFoundException) {
                 response.setMsg("文件不存在!!!");
-            }else {
+            } else {
                 response.setMsg(e.getMessage());
             }
             return response;

+ 3 - 3
jodconverter-web/src/main/java/cn/keking/utils/FileUtils.java

@@ -285,9 +285,9 @@ public class FileUtils {
      * @param name
      * @return
      */
-    private String getUrlParameterReg(String url, String name) {
+    public String getUrlParameterReg(String url, String name) {
         Map<String, String> mapRequest = new HashMap();
-        String strUrlParam = TruncateUrlPage(url);
+        String strUrlParam = truncateUrlPage(url);
         if (strUrlParam == null) {
             return "";
         }
@@ -312,7 +312,7 @@ public class FileUtils {
      * @param strURL url地址
      * @return url请求参数部分
      */
-    private static String TruncateUrlPage(String strURL) {
+    private String truncateUrlPage(String strURL) {
         String strAllParam = null;
         strURL = strURL.trim();
         String[] arrSplit = strURL.split("[?]");

+ 57 - 0
jodconverter-web/src/main/java/cn/keking/utils/FtpUtils.java

@@ -0,0 +1,57 @@
+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();
+    }
+}

+ 6 - 3
jodconverter-web/src/main/java/cn/keking/utils/SimTextUtil.java

@@ -1,6 +1,7 @@
 package cn.keking.utils;
 
 import cn.keking.config.ConfigConstants;
+import cn.keking.model.FileAttribute;
 import cn.keking.model.ReturnResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -12,12 +13,14 @@ import org.springframework.stereotype.Component;
  */
 @Component
 public class SimTextUtil {
-    String fileDir = ConfigConstants.getFileDir();
     @Autowired
-    DownloadUtils downloadUtils;
+    private FileUtils fileUtils;
+    @Autowired
+    private DownloadUtils downloadUtils;
 
     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;
     }
 }