From fbf3fe0c10ddd29190ae6839e9b6ddf33979cb2d Mon Sep 17 00:00:00 2001 From: zhouhao Date: Mon, 23 Apr 2018 18:08:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ftp=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hsweb-boost/hsweb-boost-ftp/pom.xml | 35 ++++++++ .../web/ftp/DefaultFTPOperation.java | 80 +++++++++++++++++++ .../hswebframework/web/ftp/FTPOperation.java | 35 ++++++++ .../web/ftp/pool/FTPClientFactory.java | 76 ++++++++++++++++++ .../web/ftp/pool/FTPClientPool.java | 22 +++++ .../web/ftp/pool/FTPClientProperties.java | 25 ++++++ hsweb-boost/pom.xml | 1 + 7 files changed, 274 insertions(+) create mode 100644 hsweb-boost/hsweb-boost-ftp/pom.xml create mode 100644 hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/DefaultFTPOperation.java create mode 100644 hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/FTPOperation.java create mode 100644 hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientFactory.java create mode 100644 hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientPool.java create mode 100644 hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientProperties.java diff --git a/hsweb-boost/hsweb-boost-ftp/pom.xml b/hsweb-boost/hsweb-boost-ftp/pom.xml new file mode 100644 index 000000000..c42ba2375 --- /dev/null +++ b/hsweb-boost/hsweb-boost-ftp/pom.xml @@ -0,0 +1,35 @@ + + + + hsweb-boost + org.hswebframework.web + 3.0-SNAPSHOT + + 4.0.0 + + hsweb-boost-ftp + + + + + org.apache.commons + commons-pool2 + + + commons-net + commons-net + 3.4 + + + org.springframework.boot + spring-boot-starter + true + + + org.jooq + jool-java-8 + + + \ No newline at end of file diff --git a/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/DefaultFTPOperation.java b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/DefaultFTPOperation.java new file mode 100644 index 000000000..d582239f7 --- /dev/null +++ b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/DefaultFTPOperation.java @@ -0,0 +1,80 @@ +package org.hswebframework.web.ftp; + +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import org.hswebframework.web.ftp.pool.FTPClientPool; +import org.jooq.lambda.Unchecked; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * @author zhouhao + * @since 3.0 + */ +@AllArgsConstructor +public class DefaultFTPOperation implements FTPOperation { + + private FTPClientPool pool; + + @SneakyThrows + protected FTPClient getClient() { + return pool.borrowObject(); + } + + protected void returnClient(FTPClient client) { + pool.returnObject(client); + } + + public T doExecute(Function function) { + FTPClient client = getClient(); + try { + return function.apply(client); + } finally { + returnClient(client); + } + } + + @Override + public boolean delete(String fileName) { + return doExecute(Unchecked.function(client -> client.deleteFile(fileName))); + } + + @Override + public boolean rename(String from, String to) { + return doExecute(Unchecked.function(client -> client.rename(from, to))); + } + + @Override + public boolean download(String fileName, OutputStream outputStream) { + return doExecute(Unchecked.function(client -> client.retrieveFile(fileName, outputStream))); + } + + @Override + public boolean upload(String fileName, InputStream input) { + return doExecute(Unchecked.function(client -> client.storeFile(fileName, input))); + } + + @Override + public boolean upload(String fileName, String text) { + return doExecute(Unchecked.function(client -> { + try (ByteArrayInputStream inputStream = new ByteArrayInputStream(text.getBytes())) { + return client.storeFile(fileName, inputStream); + } + })); + } + + @Override + public void list(String path, Consumer consumer) { + doExecute(Unchecked.function(client -> { + Arrays.stream(client.listFiles(path)).forEach(consumer); + return null; + })); + } +} diff --git a/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/FTPOperation.java b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/FTPOperation.java new file mode 100644 index 000000000..e76a3d09a --- /dev/null +++ b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/FTPOperation.java @@ -0,0 +1,35 @@ +package org.hswebframework.web.ftp; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * @author zhouhao + * @since 3.0 + */ +public interface FTPOperation { + + boolean delete(String fileName); + + boolean rename(String from, String to); + + boolean download(String fileName, OutputStream outputStream); + + boolean upload(String fileName, InputStream input); + + boolean upload(String fileName, String text); + + void list(String path, Consumer consumer); + + T doExecute(Function command); + + interface HandleExceptionFunction{ + T apply(FTPClient client) throws Exception; + } + +} diff --git a/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientFactory.java b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientFactory.java new file mode 100644 index 000000000..9b9306448 --- /dev/null +++ b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientFactory.java @@ -0,0 +1,76 @@ +package org.hswebframework.web.ftp.pool; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPReply; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.PooledObjectFactory; +import org.apache.commons.pool2.impl.DefaultPooledObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.ConnectException; + + +public class FTPClientFactory implements PooledObjectFactory { + private static Logger logger = LoggerFactory.getLogger(FTPClientFactory.class); + private FTPClientProperties config; + + public FTPClientFactory(FTPClientProperties config) { + this.config = config; + } + + public PooledObject makeObject() throws Exception { + FTPClient ftpClient = new FTPClient(); + ftpClient.setConnectTimeout(config.getClientTimeout()); + ftpClient.connect(config.getHost(), config.getPort()); + int reply = ftpClient.getReplyCode(); + if (!FTPReply.isPositiveCompletion(reply)) { + ftpClient.disconnect(); + logger.warn("FTPServer refused connection"); + return null; + } + boolean result = ftpClient.login(config.getUsername(), config.getPassword()); + if (!result) { + throw new ConnectException("ftp登陆失败:" + config.getUsername() + "/password:" + config.getPassword() + "@" + config.getHost()); + } + ftpClient.setFileType(config.getTransferFileType()); + ftpClient.setBufferSize(1024); + ftpClient.setControlEncoding(config.getEncoding()); + if (config.isPassiveMode()) { + ftpClient.enterLocalPassiveMode(); + } + return new DefaultPooledObject<>(ftpClient); + + } + + @Override + public void destroyObject(PooledObject p) throws Exception { + try { + p.getObject().logout(); + } finally { + p.getObject().disconnect(); + } + } + + @Override + public boolean validateObject(PooledObject p) { + try { + p.getObject().sendNoOp(); + } catch (IOException e) { + logger.warn("validateObject ftp error!", e); + return false; + } + return p.getObject().isConnected() && p.getObject().isAvailable(); + } + + @Override + public void activateObject(PooledObject p) throws Exception { + p.getObject().sendNoOp(); + } + + @Override + public void passivateObject(PooledObject p) { + + } +} \ No newline at end of file diff --git a/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientPool.java b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientPool.java new file mode 100644 index 000000000..04aa2e8e4 --- /dev/null +++ b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientPool.java @@ -0,0 +1,22 @@ +package org.hswebframework.web.ftp.pool; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.pool2.PooledObjectFactory; +import org.apache.commons.pool2.impl.AbandonedConfig; +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; + +public class FTPClientPool extends GenericObjectPool { + + public FTPClientPool(PooledObjectFactory factory) { + super(factory); + } + + public FTPClientPool(PooledObjectFactory factory, GenericObjectPoolConfig config) { + super(factory, config); + } + + public FTPClientPool(PooledObjectFactory factory, GenericObjectPoolConfig config, AbandonedConfig abandonedConfig) { + super(factory, config, abandonedConfig); + } +} diff --git a/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientProperties.java b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientProperties.java new file mode 100644 index 000000000..9f3961ae9 --- /dev/null +++ b/hsweb-boost/hsweb-boost-ftp/src/main/java/org/hswebframework/web/ftp/pool/FTPClientProperties.java @@ -0,0 +1,25 @@ +package org.hswebframework.web.ftp.pool; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; + +@Getter +@Setter +@ToString +public class FTPClientProperties extends GenericObjectPoolConfig { + private String host; + private int port = 22; + private String username; + private String password; + private boolean passiveMode = true; + private String encoding = "utf-8"; + private int clientTimeout = 10 * 1000; + private int threadNum = 20; + private int transferFileType = FTPClient.BINARY_FILE_TYPE; + private boolean renameUploaded = false; + private int retryTimes = 3; + +} \ No newline at end of file diff --git a/hsweb-boost/pom.xml b/hsweb-boost/pom.xml index 5a558471c..7f38287a2 100644 --- a/hsweb-boost/pom.xml +++ b/hsweb-boost/pom.xml @@ -32,6 +32,7 @@ hsweb-boost-validator hsweb-boost-aop + hsweb-boost-ftp