增加ftp模块

This commit is contained in:
zhouhao
2018-04-23 18:08:42 +08:00
parent 9db9d41c8d
commit fbf3fe0c10
7 changed files with 274 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hsweb-boost</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hsweb-boost-ftp</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jool-java-8</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -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> T doExecute(Function<FTPClient, T> 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<FTPFile> consumer) {
doExecute(Unchecked.function(client -> {
Arrays.stream(client.listFiles(path)).forEach(consumer);
return null;
}));
}
}

View File

@@ -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<FTPFile> consumer);
<T> T doExecute(Function<FTPClient, T> command);
interface HandleExceptionFunction<T>{
T apply(FTPClient client) throws Exception;
}
}

View File

@@ -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<FTPClient> {
private static Logger logger = LoggerFactory.getLogger(FTPClientFactory.class);
private FTPClientProperties config;
public FTPClientFactory(FTPClientProperties config) {
this.config = config;
}
public PooledObject<FTPClient> 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<FTPClient> p) throws Exception {
try {
p.getObject().logout();
} finally {
p.getObject().disconnect();
}
}
@Override
public boolean validateObject(PooledObject<FTPClient> 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<FTPClient> p) throws Exception {
p.getObject().sendNoOp();
}
@Override
public void passivateObject(PooledObject<FTPClient> p) {
}
}

View File

@@ -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<FTPClient> {
public FTPClientPool(PooledObjectFactory<FTPClient> factory) {
super(factory);
}
public FTPClientPool(PooledObjectFactory<FTPClient> factory, GenericObjectPoolConfig config) {
super(factory, config);
}
public FTPClientPool(PooledObjectFactory<FTPClient> factory, GenericObjectPoolConfig config, AbandonedConfig abandonedConfig) {
super(factory, config, abandonedConfig);
}
}

View File

@@ -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;
}

View File

@@ -32,6 +32,7 @@
<modules>
<module>hsweb-boost-validator</module>
<module>hsweb-boost-aop</module>
<module>hsweb-boost-ftp</module>
</modules>