最近在写一个项目,需要用到FTP服务,就从网上搜了一下,发现Apache Ftp Server相对来说使用方便,性能稳定,效率高,且该服务器是开源免费的,而且该服务器与spring容器可以无缝的融合到一起,下面是我写的一个例子,供有需要的参考。
第一步:下载jar包,拷贝到项目的lib目录下,jar包请参照附件
第二步:添加配置文件ftpserver.xml,具体内容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:beans="http://www.springframework.org/schema/beans"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd">
- <!-- FTP服务器启动参数配置 -->
- <server xmlns="http://mina.apache.org/ftpserver/spring/v1"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd"
- id="ftpServer"
- max-logins="500"
- anon-enabled="false"
- max-anon-logins="0"
- max-login-failures="3"
- login-failure-delay="500">
- <listeners>
- <nio-listener name="default" port="2121" idle-timeout="60">
- <ssl>
- <keystore file="ftpserver.jks" password="password" />
- </ssl>
- </nio-listener>
- </listeners>
- <!-- <file-user-manager file="users.properties" /> -->
- <db-user-manager>
- <data-source>
- <beans:bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <beans:property name="driverClass" value="${jdbc.driverClassName}" />
- <beans:property name="jdbcUrl" value="${jdbc.url}" />
- <beans:property name="user" value="${jdbc.username}" />
- <beans:property name="password" value="${jdbc.password}" />
- </beans:bean>
- </data-source>
- <insert-user>
- INSERT INTO FtpUser
- (userid, userpassword, homedirectory, enableflag, writepermission, idletime, uploadrate, downloadrate)
- VALUES
- ('{userid}', '{userpassword}', '{homedirectory}', true, true, {idletime}, {uploadrate}, {downloadrate})
- </insert-user>
- <update-user>
- UPDATE FtpUser SET
- userpassword='{userpassword}',
- homedirectory='{homedirectory}',
- enableflag={enableflag},
- writepermission={writepermission},
- idletime={idletime},
- uploadrate={uploadrate},
- downloadrate={downloadrate}
- WHERE
- userid='{userid}'
- </update-user>
- <delete-user>DELETE FROM FtpUser WHERE userid = '{userid}'</delete-user>
- <select-user>
- SELECT
- userid, userpassword, homedirectory,
- enableflag, writepermission, idletime, uploadrate, downloadrate,
- maxloginnumber, maxloginperip
- FROM
- FtpUser
- WHERE
- userid = '{userid}'
- </select-user>
- <select-all-users>SELECT userid FROM FtpUser ORDER BY userid</select-all-users>
- <is-admin>
- SELECT userid FROM FtpUser WHERE userid='{userid}' AND userid='admin'
- </is-admin>
- <authenticate>SELECT userpassword from FtpUser WHERE userid='{userid}'</authenticate>
- </db-user-manager>
- </server>
- </beans>
注:FTP用户的管理方式我使用的是数据库的方式
data-source里面的beans:property值都是从jdbc.properties中获取的,资源值是通过spring获取的
- <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath:jdbc.properties</value>
- </list>
- </property>
- </bean>
jdbc.properties内容请参照附件
把该文件导入到spring配置文件中,代码如下:
- <!-- 导入FTP SERVER配置 -->
- <import resource="classpath:/ftpserver.xml"/>
第三步:拷贝ftpserver.jks文件到src目录,该文件在apache-ftpserver-1.0.6\res目录下
第四步:建立FTP服务监听类FtpServerListener,代码如下:
- package com.blingtel.ftp;
- import java.io.File;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.ftpserver.ftplet.UserManager;
- import org.apache.ftpserver.impl.DefaultFtpServer;
- import org.springframework.web.context.WebApplicationContext;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import com.blingtel.util.Global;
- /**
- * <FTP SERVER操作类>
- * <功能详细描述>
- * @author wenkaixuan
- * @version [版本号, 2014-3-31]
- * @see [相关类/方法]
- * @since [产品/模块版本]
- */
- public class FtpServerListener implements ServletContextListener
- {
- /**
- * 日志对象
- */
- private Log logger = LogFactory.getLog(FtpServerListener.class);
- /**
- * {@inheritDoc}
- */
- public void contextDestroyed(ServletContextEvent sce)
- {
- logger.error("Stopping FtpServer");
- DefaultFtpServer server = (DefaultFtpServer)sce.getServletContext().getAttribute("FTPSERVER_CONTEXT_NAME");
- if (server != null)
- {
- server.stop();
- sce.getServletContext().removeAttribute("FTPSERVER_CONTEXT_NAME");
- logger.error("FtpServer stopped");
- }
- else
- {
- logger.error("No running FtpServer found");
- }
- }
- /**
- * {@inheritDoc}
- */
- public void contextInitialized(ServletContextEvent sce)
- {
- logger.error("Starting FtpServer");
- WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
- DefaultFtpServer server = (DefaultFtpServer)ctx.getBean("ftpServer");
- sce.getServletContext().setAttribute("FTPSERVER_CONTEXT_NAME", server);
- try
- {
- // 获取操作系统
- String osName = System.getProperty("os.name");
- // 如果是windows系統
- if (osName.toLowerCase().indexOf("windows") > -1)
- {
- // 设置FTP路径
- Global.ftpPath = "C:\\ftpServer";
- }
- else
- {
- // 设置FTP路径
- Global.ftpPath = "/home/ftpServer";
- }
- // 判断该路径是否存在,如果不存在则创建
- File file = new File(Global.ftpPath);
- if (!file.exists())
- {
- file.mkdirs();
- }
- // 更新FTP服务器用户信息
- // 首先获取到FTP用户管理对象
- UserManager userManage = server.getUserManager();
- // 删除原有的用户信息
- userManage.delete(Global.ftpUserName);
- // 构造新的用户并保存到数据库
- BaseUser base = new BaseUser();
- base.setName(Global.ftpUserName);
- base.setPassword(Global.ftpPassword);
- base.setHomeDirectory(Global.ftpPath);
- userManage.save(base);
- // 启动FTP服务
- server.start();
- logger.error("FtpServer started");
- }
- catch (Exception e)
- {
- logger.error("Failed to start FtpServer");
- logger.error(Global.LOG_EXCEPTION_NAME, e);
- }
- }
- }
在web.xml中配置该监听器,代码如下:
- <!-- Spring 容器启动监听器 -->
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- <listener-class>com.blingtel.ftp.FtpServerListener</listener-class>
- </listener>
第五步:建立FTP用户实体类,用于实现用户的增删查,该实体类必须要实现User接口,代码如下:
- package com.blingtel.ftp;
- import java.util.List;
- import org.apache.ftpserver.ftplet.Authority;
- import org.apache.ftpserver.ftplet.AuthorizationRequest;
- import org.apache.ftpserver.ftplet.User;
- /**
- * <一句话功能简述>
- * <功能详细描述>
- * @author wenkaixuan
- * @version [版本号, 2014-3-31]
- * @see [相关类/方法]
- * @since [产品/模块版本]
- */
- public class BaseUser implements User
- {
- private String name;
- private String password;
- private String homeDirectory;
- public void setName(String name)
- {
- this.name = name;
- }
- public void setPassword(String password)
- {
- this.password = password;
- }
- public void setHomeDirectory(String homeDirectory)
- {
- this.homeDirectory = homeDirectory;
- }
- public AuthorizationRequest authorize(AuthorizationRequest arg0)
- {
- return null;
- }
- public List<Authority> getAuthorities()
- {
- return null;
- }
- public List<Authority> getAuthorities(Class<? extends Authority> arg0)
- {
- return null;
- }
- public boolean getEnabled()
- {
- return true;
- }
- public String getHomeDirectory()
- {
- return homeDirectory;
- }
- public int getMaxIdleTime()
- {
- return 0;
- }
- public String getName()
- {
- return name;
- }
- public String getPassword()
- {
- return password;
- }
- /**
- * @return 返回 writepermission
- */
- public boolean getWritePermission()
- {
- return true;
- }
- }
通过以上代码就可以实现FTP服务跟随项目的的启动而启动,停止而停止,并且在FTP服务启动时可以添加一个名称是Global.ftpUserName的用户到数据库
另外,FTP用户表结构如下:
- #FTP用户信息表
- create table FtpUser
- (
- 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
- );