首先在application.xml(spring配置文件)添加Apache Ftpserver属性
<server xmlns="http://mina.apache.org/ftpserver/spring/v1" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd " id="myServer" max-logins="500" anon-enabled="false" max-login-failures="20" login-failure-delay="30" > <listeners> <!-- port为FTP端口默认为21 idle-timeout为登录失效时间单位s--> <nio-listener name="default" port="2121" idle-timeout="300"> <!--<ssl> ssl数据传输加密 <keystore file="ftpserver.jks" password="password" /> </ssl>--> </nio-listener> </listeners> <!--FTP操作监听--> <ftplets> <ftplet name="ftplet1"> <beans:bean class="com.agnet.service.FtpService"> <!--属性注入--> <!-- <beans:property name="foo" value="123" />--> </beans:bean> </ftplet> </ftplets> <!--properties文件存放用户信息 encrypt-passwords 默认为MD5加密,clear为明文密码,salted为加强MD5加密--> <!--<file-user-manager file="users.properties" encrypt-passwords="clear"/>--> <!-- 数据库存放用户信息 建表SQL CREATE TABLE FTP_USER ( userid VARCHAR(64) NOT NULL PRIMARY KEY, userpassword VARCHAR(64), homedirectory VARCHAR(128) NOT NULL, enableflag char(1) DEFAULT 1 check (enableflag in(0,1)), writepermission char(1) DEFAULT 1 check (writepermission in(0,1)), idletime INT DEFAULT 0, uploadrate INT DEFAULT 0, downloadrate INT DEFAULT 0, maxloginnumber INT DEFAULT 0, maxloginperip INT DEFAULT 0 ); --> <db-user-manager encrypt-passwords="salted"> <data-source> <beans:bean class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <beans:property name="driverClass" value="${common.c3p0.driver}" /> <beans:property name="jdbcUrl" value="${common.c3p0.url}" /> <beans:property name="user" value="${common.c3p0.username}" /> <beans:property name="password" value="${common.c3p0.password}" /> </beans:bean> </data-source> <!--当为数据库存放时 apache FTPserver APi 函数需要调用的sql --> <insert-user>INSERT INTO FTP_USER (userid, userpassword, homedirectory, enableflag, writepermission, idletime, uploadrate, downloadrate,maxloginnumber,maxloginperip) VALUES ('{userid}', '{userpassword}', '{homedirectory}', '{enableflag}', '{writepermission}', {idletime}, {uploadrate}, {downloadrate},{maxloginnumber},{maxloginperip})</insert-user> <update-user> 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}' </update-user> <delete-user> DELETE FROM FTP_USER WHERE userid = '{userid}' </delete-user> <select-user> SELECT userid, userpassword, homedirectory, enableflag, writepermission, idletime, uploadrate, downloadrate,maxloginnumber,maxloginperip FROM FTP_USER WHERE userid = '{userid}' </select-user> <select-all-users> SELECT userid FROM FTP_USER ORDER BY userid </select-all-users> <is-admin> SELECT userid FROM FTP_USER WHERE userid='{userid}' AND userid='admin' </is-admin> <authenticate>SELECT userpassword from FTP_USER WHERE userid='{userid}'</authenticate> </db-user-manager> </server>
在web.xml中添加自己的容器启动关闭监听,目的是操作FTPserver
Web.xml:
<!-- 容器 初始化监听 --> <listener> <listener-class>com.base.listener.MyServletContextListener</listener-class> </listener>
MyServletContextListener.java:
public class MyServletContextListener implements ServletContextListener { public static final String FTPSERVER_CONTEXT_NAME = "org.apache.ftpserver"; //容器销毁 public void contextDestroyed(ServletContextEvent sce) { System.out.println("Stopping FtpServer"); //停止FTP server FtpServer server = (FtpServer) sce.getServletContext().getAttribute(FTPSERVER_CONTEXT_NAME); if(server != null) { server.stop(); sce.getServletContext().removeAttribute(FTPSERVER_CONTEXT_NAME); System.out.println("FtpServer stopped"); } else { System.out.println("No running FtpServer found"); } } //容器初始化 public void contextInitialized(ServletContextEvent sce) { /*在此如不希望容器启动里就开启FTPserver而是希望在页面通过手动开启 System.out.println("Starting FtpServer"); WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); FtpServer server = (FtpServer) ctx.getBean("myServer"); sce.getServletContext().setAttribute(FTPSERVER_CONTEXT_NAME, server); try { server.start(); System.out.println("FtpServer started"); } catch (Exception e) { throw new RuntimeException("Failed to start FtpServer", e); }*/ } }
/** * 开启FTPServer * @param servletContext 可以从action中获得也可以ServletActionContext.getServletContext(); */ public boolean startFtpServer(ServletContext servletContext) { System.out.println("Starting FtpServer"); boolean flg = true; try { FtpServer server = (FtpServer) servletContext.getAttribute(MyServletContextListener.FTPSERVER_CONTEXT_NAME); if(server != null) { if(server.isSuspended()) server.resume();//恢复 }else{ WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext); server = (FtpServer) ctx.getBean("myServer"); servletContext.setAttribute(MyServletContextListener.FTPSERVER_CONTEXT_NAME, server); server.start(); } System.out.println("FtpServer started"); } catch (Exception e) { flg = false; throw new RuntimeException("Failed to start FtpServer", e); } return flg; }
//由于apache FTPserver不提供重启功能如果需要手动关闭serve可以将其进行挂起,以方便恢复 /** * 关闭FTPServer * @param servletContext * @return */ public boolean stopFtpServer(ServletContext servletContext) { System.out.println("Stopping FtpServer"); FtpServer server = (FtpServer) servletContext.getAttribute(MyServletContextListener.FTPSERVER_CONTEXT_NAME); if(server != null) { if(!server.isStopped()&&!server.isSuspended()) server.suspend(); //servletContext.removeAttribute(FtpServerListener.FTPSERVER_CONTEXT_NAME); System.out.println("FtpServer suspend"); } else { System.out.println("No running FtpServer found"); } return true; }
//对用户进行操作 /** * 申请FTP帐号 * @param userName * @param sce * @return * @throws FtpException */ public String applyAccount(String userName, ServletContext sce) throws FtpException { String psw=""; //PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); //File f = new File(AgentFileService.class.getClassLoader().getResource("users.properties").getFile()); //userManagerFactory.setFile(f); //DbUserManagerFactory userManagerFactory = new DbUserManagerFactory(); //明文密码保存于配置文件中 发面时改为MD5加密 同时修改配置文件applictionContext-ftp //userManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor()); //UserManager um = userManagerFactory.createUserManager(); DefaultFtpServer server = (DefaultFtpServer) sce.getAttribute(MyServletContextListener.FTPSERVER_CONTEXT_NAME); if(server!=null){ UserManager um = server.getUserManager(); if(um.doesExist(userName)){ um.delete(userName); } psw = RandomStringUtils.randomAlphanumeric(8); UserFactory userFact = new UserFactory(); userFact.setName(userName); userFact.setPassword(psw); userFact.setHomeDirectory("/home/myftpPath"); userFact.setMaxIdleTime(600000);//10分钟无操作自动断开连接 List<Authority> alist = new ArrayList<Authority>(); Authority a = new WritePermission();//写权限 alist.add(a); userFact.setAuthorities(alist); User user = userFact.createUser(); um.save(user); } return psw; } //删除用户 DefaultFtpServer server = (DefaultFtpServer) servletContext.getAttribute(MyServletContextListener.FTPSERVER_CONTEXT_NAME); if (server != null) { UserManager um = server.getUserManager(); String[] users = um.getAllUserNames(); if (users != null && users.length > 0) { for (String userName : users) { if (!userName.equals(‘admin’) && um.doesExist(userName)) { um.delete(userName); } } } }
FTP操作监听
FtpService.java:
public class FtpService extends DefaultFtplet{ @Override public FtpletResult onUploadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { return super.onUploadStart(session, request); } @Override public void init(FtpletContext ftpletContext) throws FtpException { // TODO Auto-generated method stub super.init(ftpletContext); } @Override public void destroy() { // TODO Auto-generated method stub super.destroy(); } @Override public FtpletResult onConnect(FtpSession session) throws FtpException, IOException { // TODO Auto-generated method stub return super.onConnect(session); } @Override public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException { // TODO Auto-generated method stub return super.onDisconnect(session); } @Override public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.beforeCommand(session, request); } @Override public FtpletResult afterCommand(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException { // TODO Auto-generated method stub return super.afterCommand(session, request, reply); } @Override public FtpletResult onLogin(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onLogin(session, request); } @Override public FtpletResult onDeleteStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onDeleteStart(session, request); } @Override public FtpletResult onDeleteEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onDeleteEnd(session, request); } @Override public FtpletResult onUploadStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onUploadStart(session, request); } @Override public FtpletResult onDownloadStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onDownloadStart(session, request); } @Override public FtpletResult onDownloadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onDownloadEnd(session, request); } @Override public FtpletResult onRmdirStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onRmdirStart(session, request); } @Override public FtpletResult onRmdirEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onRmdirEnd(session, request); } @Override public FtpletResult onMkdirStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onMkdirStart(session, request); } @Override public FtpletResult onMkdirEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onMkdirEnd(session, request); } @Override public FtpletResult onAppendStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onAppendStart(session, request); } @Override public FtpletResult onAppendEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onAppendEnd(session, request); } @Override public FtpletResult onUploadUniqueStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onUploadUniqueStart(session, request); } @Override public FtpletResult onUploadUniqueEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onUploadUniqueEnd(session, request); } @Override public FtpletResult onRenameStart(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onRenameStart(session, request); } @Override public FtpletResult onRenameEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onRenameEnd(session, request); } @Override public FtpletResult onSite(FtpSession session, FtpRequest request) throws FtpException, IOException { // TODO Auto-generated method stub return super.onSite(session, request); } }