当前位置 主页 > 网站技术 > 代码类 >

    springboot整合apache ftpserver详细教程(推荐)(2)

    栏目:代码类 时间:2021-08-13 15:42

    3、启动并访问

    首先启动服务,打开cmd并cd到bin路径执行.\ftpd.bat res/conf/ftpd-typical.xml,看到如下状态说明启动成功

    测试访问,打开浏览器输入:ftp://localhost:2121/就会看到你的文件目录了,如果没有配置匿名用户,则会要求你输入用户名密码,正是你在user.properties中配置的

    四、Springboot整合Apache ftpserver(重点)

    方式一:独立部署ftpserver服务

      这种方式比较简单,只要把服务部署好即可,然后通过FtpClien来完成相关操作,同jedis访问redis服务一个道理,没啥可说的。主要注意一下ftpserver的访问模式,如果要支持外网连接,需要使用被动模式passive。

    方式二:将ftpserver服务内嵌到springboot服务中

      这种方式需要和springboot整合在一起,相对比较复杂,但这种方式下ftpserver会 随着springboot服务启动或关闭而开启或销毁。具体使用哪种方式就看自己的业务需求了。

      简单说一下我的实现的方案,ftpserver支持配置文件和db两种方式来保存账号信息和其它相关配置,如果我们的业务系统需要将用户信息和ftp的账号信息打通,并且还有相关的业务统计,比如统计系统中每个人上传文件的时间、个数等等,那么使用数据库来保存ftp账号信息还是比较方便灵活的。我这里就选择使用mysql了。

    开始整合

    1、项目添加依赖

     

    //这些只是apache ftpserver相关的依赖,springboot项目本身的依赖大家自己添加即可
    <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
     <version>1.7.25 </version>
    </dependency>
    <dependency>
     <groupId>org.apache.ftpserver</groupId>
     <artifactId>ftpserver-core</artifactId>
     <version>1.1.1</version>
    </dependency>
    <dependency>
     <groupId>org.apache.ftpserver</groupId>
     <artifactId>ftplet-api</artifactId>
     <version>1.1.1</version>
    </dependency>
    
    <dependency>
     <groupId>org.apache.mina</groupId>
     <artifactId>mina-core</artifactId>
     <version>2.0.16</version>
    </dependency> 

     

    2、数据库建表用来保存相关的账户信息(大家可以手动添加几条用来测试),具体字段意思参考users.properties文件配置(可以想象一下以后我们的系统每注册一个用户都可以为其添加一条ftp_user信息,用来指定保存用户的上传数据等等)

     

    CREATE TABLE FTP_USER (  
     userid VARCHAR(64) NOT NULL PRIMARY KEY,  
     userpassword VARCHAR(64),  
     homedirectory VARCHAR(128) NOT NULL,    
     enableflag BOOLEAN DEFAULT TRUE, 
     writepermission BOOLEAN DEFAULT FALSE,  
     idletime INT DEFAULT 0,    
     uploadrate INT DEFAULT 0,    
     downloadrate INT DEFAULT 0,
     maxloginnumber INT DEFAULT 0,
     maxloginperip INT DEFAULT 0
    );

    3、配置ftpserver,提供ftpserver的init()、start()、stop()方法

     

    import com.mysql.cj.jdbc.MysqlDataSource;
    import com.talkingdata.tds.ftpserver.plets.MyFtpPlet;
    import org.apache.commons.io.IOUtils;
    import org.apache.ftpserver.DataConnectionConfigurationFactory;
    import org.apache.ftpserver.FtpServer;
    import org.apache.ftpserver.FtpServerFactory;
    import org.apache.ftpserver.ftplet.FtpException;
    import org.apache.ftpserver.ftplet.Ftplet;
    import org.apache.ftpserver.listener.Listener;
    import org.apache.ftpserver.listener.ListenerFactory;
    import org.apache.ftpserver.ssl.SslConfigurationFactory;
    import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor;
    import org.apache.ftpserver.usermanager.DbUserManagerFactory;
    import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.stereotype.Component;
    import javax.sql.DataSource;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    /**
     * 注意:被@Configuration标记的类会被加入ioc容器中,而且类中所有带 @Bean注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。
     * ftp服务访问地址:
     *  ftp://localhost:3131/
     */
    @Configuration("MyFtp")
    public class MyFtpServer {
     private static final Logger logger = LoggerFactory.getLogger(MyFtpServer.class);
     //springboot配置好数据源直接注入即可
     @Autowired
     private DataSource dataSource;
     protected FtpServer server;
     //我们这里利用spring加载@Configuration的特性来完成ftp server的初始化
     public MyFtpServer(DataSource dataSource) {
      this.dataSource = dataSource;
      initFtp();
      logger.info("Apache ftp server is already instantiation complete!");
     }
     /**
      * ftp server init
      * @throws IOException
      */
     public void initFtp() {
      FtpServerFactory serverFactory = new FtpServerFactory();
      ListenerFactory listenerFactory = new ListenerFactory();
      //1、设置服务端口
      listenerFactory.setPort(3131);
      //2、设置被动模式数据上传的接口范围,云服务器需要开放对应区间的端口给客户端
      DataConnectionConfigurationFactory dataConnectionConfFactory = new DataConnectionConfigurationFactory();
      dataConnectionConfFactory.setPassivePorts("10000-10500");
      listenerFactory.setDataConnectionConfiguration(dataConnectionConfFactory.createDataConnectionConfiguration());
      //3、增加SSL安全配置
    //  SslConfigurationFactory ssl = new SslConfigurationFactory();
    //  ssl.setKeystoreFile(new File("src/main/resources/ftpserver.jks"));
    //  ssl.setKeystorePassword("password");
      //ssl.setSslProtocol("SSL");
      // set the SSL configuration for the listener
    //  listenerFactory.setSslConfiguration(ssl.createSslConfiguration());
    //  listenerFactory.setImplicitSsl(true);
      //4、替换默认的监听器
      Listener listener = listenerFactory.createListener();
      serverFactory.addListener("default", listener);
      //5、配置自定义用户事件
      Map<String, Ftplet> ftpLets = new HashMap();
      ftpLets.put("ftpService", new MyFtpPlet());
      serverFactory.setFtplets(ftpLets);
      //6、读取用户的配置信息
      //注意:配置文件位于resources目录下,如果项目使用内置容器打成jar包发布,FTPServer无法直接直接读取Jar包中的配置文件。
      //解决办法:将文件复制到指定目录(本文指定到根目录)下然后FTPServer才能读取到。
    //  PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
    //  String tempPath = System.getProperty("java.io.tmpdir") + System.currentTimeMillis() + ".properties";
    //  File tempConfig = new File(tempPath);
    //  ClassPathResource resource = new ClassPathResource("users.properties");
    //  IOUtils.copy(resource.getInputStream(), new FileOutputStream(tempConfig));
    //  userManagerFactory.setFile(tempConfig);
    //  userManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor()); //密码以明文的方式
    //  serverFactory.setUserManager(userManagerFactory.createUserManager());
      //6.2、基于数据库来存储用户实例
      DbUserManagerFactory dbUserManagerFactory = new DbUserManagerFactory();
      //todo....
      dbUserManagerFactory.setDataSource(dataSource);
      dbUserManagerFactory.setAdminName("admin");
      dbUserManagerFactory.setSqlUserAdmin("SELECT userid FROM FTP_USER WHERE userid='{userid}' AND userid='admin'");
      dbUserManagerFactory.setSqlUserInsert("INSERT INTO FTP_USER (userid, userpassword, homedirectory, " +
        "enableflag, writepermission, idletime, uploadrate, downloadrate) VALUES " +
        "('{userid}', '{userpassword}', '{homedirectory}', {enableflag}, " +
        "{writepermission}, {idletime}, uploadrate}, {downloadrate})");
      dbUserManagerFactory.setSqlUserDelete("DELETE FROM FTP_USER WHERE userid = '{userid}'");
      dbUserManagerFactory.setSqlUserUpdate("UPDATE FTP_USER SET userpassword='{userpassword}',homedirectory='{homedirectory}',enableflag={enableflag},writepermission={writepermission},idletime={idletime},uploadrate={uploadrate},downloadrate={downloadrate},maxloginnumber={maxloginnumber}, maxloginperip={maxloginperip} WHERE userid='{userid}'");
      dbUserManagerFactory.setSqlUserSelect("SELECT * FROM FTP_USER WHERE userid = '{userid}'");
      dbUserManagerFactory.setSqlUserSelectAll("SELECT userid FROM FTP_USER ORDER BY userid");
      dbUserManagerFactory.setSqlUserAuthenticate("SELECT userid, userpassword FROM FTP_USER WHERE userid='{userid}'");
      dbUserManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());
      serverFactory.setUserManager(dbUserManagerFactory.createUserManager());
      //7、实例化FTP Server
      server = serverFactory.createServer();
     }
     /**
      * ftp server start
      */
     public void start(){
      try {
       server.start();
       logger.info("Apache Ftp server is starting!");
      }catch(FtpException e) {
       e.printStackTrace();
      }
     }
     /**
      * ftp server stop
      */
     public void stop() {
      server.stop();
      logger.info("Apache Ftp server is stoping!");
     }
    }