zoukankan      html  css  js  c++  java
  • Apache FtpServer扩展【动手实现自己的业务】

    Apache FtpServer是当下最热门的走ftp协议的用于用户上传下载的服务器。
     
    一般来说,用的话,去官网下载完整的项目文件ftpserver-1.0.6.zip【windows版】和ftpserver-1.0.6.tar.gz【linux版】到本地,解压之后配置一下\ftpserver-1.0.6\apache-ftpserver-1.0.6\res\conf\下的users.properties或者ftpd-full.xml【主要看你走什么样的用户验证方式。users.properties:把用户信息配置在这个文件中。ftpd-full.xml:把用户信息配置在数据库中】
    这样去bin目录下启动程序就好了。
     
    但是Apache FtpServer从官方文档来看,都没有提及如何改变其中一些功能,只是解释一些它提供的标准功能。
    这样对于企业级的应用来说,有些功能并不能满足现有的业务。
     
    比如,我想限制每个ftp用户上传文件到他的文件目录下时,我想限制每个用户最多上传文件的总大小不超过50M。因为我不想被恶意用户弄爆我的服务器。我查阅了大量资料,发现标准的官方版里面是没有这样的功能的,在ftpd-full.xml和users.properties这里面也没有任何可以修改的参数来控制这样的业务。最后我决定自己通过编程来实现这样一个专门服务于我的这样的FtpServer。
    我有这种想法的原因是,Apache FtpServer是纯java写的服务,而且提供了丰富的java接口。
     
    查阅了大量资料后,还是找不到怎么用代码从jar里面启动整个server。
    最后用反编译工具反编译整个Apache FtpServer项目后发现了,找到了启动的入口。
     1 public MyFtpServer() throws FtpException{
     2         
     3         //读取my-ftpd-full.xml,连接数据库和监控配置,然后来启动server
     4         FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(xmlPath);
     5         FtpServer server = null;
     6         if (ctx.containsBean("server")) {
     7             server = (FtpServer)ctx.getBean("server");
     8          } else {
     9             String[] beanNames = ctx.getBeanNamesForType(FtpServer.class);
    10             if (beanNames.length == 1) {
    11                 server = (FtpServer)ctx.getBean(beanNames[0]);
    12             } else if (beanNames.length > 1) {
    13                 logger.info("Using the first server defined in the configuration, named " + beanNames[0]);
    14                 server = (FtpServer)ctx.getBean(beanNames[0]);
    15             } else {
    16                 logger.info("XML configuration does not contain a server configuration");
    17             }
    18         }
    19         
    20         //ftp服务器启动
    21         server.start();
    22         
    23         //在jvm关闭的时候,清理函数
    24         addShutdownHook(server);
    25     }
    26     
    27     /**
    28      * 清理的垃圾的钩子函数
    29      * @param engine
    30      */
    31     private void addShutdownHook(final FtpServer engine)
    32       {
    33         Runnable shutdownHook = new Runnable() {
    34           public void run() {
    35            logger.info("Stopping server...");
    36             engine.stop();
    37           }
    38         };
    39         Runtime runtime = Runtime.getRuntime();
    40         runtime.addShutdownHook(new Thread(shutdownHook));
    41       }
    配合上我的研究发现,提供的接口中可以在ftpd-full.xml中配置
     
     
        <ftplets>
            <ftplet name="MyFtplet">
                <beans:bean class="com.shiyi.km.ftpserver.control.MyFtplet">
    <!--                 <beans:property name="foo" value="123" /> -->
                </beans:bean>
            </ftplet>
        </ftplets>
    类似于监听器的东西,可以监听每个用户在上传或者下载的动作,在这些监听事件里面,我每次都去计算那个用户目录下面的文件size总大小,如果超过限制,就stop,并返回警告代码和消息给用户。
     
     1 import java.io.File;
     2 import java.io.IOException;
     3 
     4 import org.apache.ftpserver.ftplet.DefaultFtpReply;
     5 import org.apache.ftpserver.ftplet.DefaultFtplet;
     6 import org.apache.ftpserver.ftplet.FtpException;
     7 import org.apache.ftpserver.ftplet.FtpRequest;
     8 import org.apache.ftpserver.ftplet.FtpSession;
     9 import org.apache.ftpserver.ftplet.FtpletResult;
    10 import org.apache.ftpserver.ftplet.User;
    11 import org.apache.log4j.Logger;
    12 
    13 import com.shiyi.km.ftpserver.util.ConfigUtil;
    14 import com.shiyi.km.ftpserver.util.FileUtil;
    15 
    16 /**
    17  * 
    18  * @fileName MyFtplet.java
    19  * @author chenkaideng
    20  * @date 2015年8月11日
    21  * @describe 监控事件
    22  */
    23 public class MyFtplet extends DefaultFtplet{
    24     private static final Logger logger = Logger.getLogger(MyFtplet.class);
    25     
    26     
    27     @Override
    28     public FtpletResult onUploadStart(FtpSession session, FtpRequest request)
    29             throws FtpException, IOException {
    30         //获取用户信息
    31         User user = session.getUser();
    32         logger.info(String.format("用户信息,用户名【%s】,用户工作目录【%s】", user.getName(),user.getHomeDirectory()));
    33         File file=new File(user.getHomeDirectory());
    34         
    35         //判断传入对象是否为一个文件夹对象
    36         if(!file.isDirectory()){
    37             logger.info("用户的HomeDirectory不是一个文件夹,请检查路径是否有误!!");
    38         }
    39         else{
    40             ConfigUtil configUtil = ConfigUtil.getInstance();
    41             if(FileUtil.overSizeLimit(configUtil.getQuota(), file)){
    42                 logger.error(String.format("目前用户[%s]目录下的文件总大小超过配额!!!", user.getName()));
    43                 session.write(new DefaultFtpReply(228, "The files under the directory over quota"));
    44                 return FtpletResult.DISCONNECT; 
    45             }
    46         }
    47         return super.onUploadStart(session, request);
    48     }
    51 }
    差不多整体的思路是这样的。
     
     
    有了这些基础,还可以实现各种各样的不同需求,来管理用户目录或者一些其他的业务。
  • 相关阅读:
    jQuery插件 -- 表单验证插件jquery.validate.js
    jQuery插件 -- Form表单插件jquery.form.js<转>
    win7 64位安装oracle10g客户端心得
    用STS创建Maven的Web项目<转>
    分别通过【buildpath】和【lib】倒入JAR包有什么不同
    利用AbstractRoutingDataSource实现动态数据源切换
    mybatis分页
    Java基本功—Reference
    Java中 堆 栈,常量池等概念解析(转载)
    RTSP流媒体转发服务器源码
  • 原文地址:https://www.cnblogs.com/chenkaideng/p/4886018.html
Copyright © 2011-2022 走看看