[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mina-commits
Subject:    [CONF] Apache MINA FtpServer > Ftplet
From:       confluence () apache ! org
Date:       2011-02-23 12:42:00
Message-ID: 23092793.7407.1298464920022.JavaMail.root () thor
[Download RAW message or body]

<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" \
href="/confluence/s/2036/9/1/_/styles/combined.css?spaceKey=FTPSERVER&amp;forWysiwyg=true" \
type="text/css">  </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/FTPSERVER/Ftplet">Ftplet</a></h2>
  <h4>Page <b>edited</b> by             <a \
href="https://cwiki.apache.org/confluence/display/~ngn">Niklas Gustavsson</a>  </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The Ftplet interface supports two \
lifecycle methods to provide initialization (the init() method) and shutdown (the \
destroy() method). Main processing is done in different notification methods, which \
take a FtpSession object and a FtpRequest object. All the notification methods return \
FtpletResult object to indicate the future action. <br> <br></td></tr>  <tr><td \
class="diff-changed-lines" >There will be one instance of Ftplet object. Notification \
methods will be called from different connections running in different threads. So \
Ftplet implementation has to be thread-safe. Each connection will have its own \
request (FtpRequest) and session <span \
class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">(FtpRequest)</span> \
<span class="diff-added-words"style="background-color: #dfd;">(FtpSession)</span> \
                objects. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. Main Classes <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Ftplet-Overview"></a>Overview</h2>

<p>The Ftplet API is a simple API used to handle different FtpServer notifications. \
Apache FtpServer is a Ftplet container, allowing administrators to deploy Ftplet to \
carry out a variety of complex FTP event handler tasks.</p>

<p>Implementing a custom Ftplet is generally a simple task, most of whose complexity \
lies in coding the actual work to be done by the Ftplet. This is largely due to the \
simplicity of the Ftplet interface and the fact that a DefaultFtplet class is \
provided as part of the Ftplet package.</p>

<p>The Ftplet interface supports two lifecycle methods to provide initialization (the \
init() method) and shutdown (the destroy() method). Main processing is done in \
different notification methods, which take a FtpSession object and a FtpRequest \
object. All the notification methods return FtpletResult object to indicate the \
future action.</p>

<p>There will be one instance of Ftplet object. Notification methods will be called \
from different connections running in different threads. So Ftplet implementation has \
to be thread-safe. Each connection will have its own request (FtpRequest) and session \
(FtpSession) objects. </p>

<h2><a name="Ftplet-MainClasses"></a>Main Classes</h2>

<h3><a name="Ftplet-FtpletResult"></a>FtpletResult</h3>

<p>This class encapsulates the return values of the ftplet methods. There are four \
static FtpletResult values.</p> <ul>
	<li><b>DEFAULT</b> : This return value indicates that the next ftplet method will be \
called. If no other ftplet is available, the FtpServer will process the request.</li> \
<li><b>NO_FTPLET</b> : This return value indicates that the other ftplet methods will \
not be called but the FtpServer will continue processing this request.</li>  \
<li><b>SKIP</b> : It indicates that the server will skip everything. No further \
processing will be done for this request.</li>  <li><b>DISCONNECT</b> : It indicates \
that the server will skip and disconnect the client. No other request from the same \
client will be served.</li> </ul>


<p> So, DEFAULT &lt; NO_FTPLET &lt; SKIP &gt; DISCONNECT. If the Ftplet returns null, \
DEFAULT is assumed.</p>

<h3><a name="Ftplet-FtpSession"></a>FtpSession</h3>
<p>The session object is kept for the entire user session. So the attributes set by \
<em>setAttribute()</em> will be always available later unless that attribute is \
removed. Different session will have different FtpSession objects. From here we can \
get user information, data streams, user file system view etc.</p>

<p>Ftplets can use this to send custom codes and messages to client.</p>

<h3><a name="Ftplet-FtpRequest"></a>FtpRequest</h3>

<p>Provides the client request information to a ftplet. Contains the FTP command and \
argument.</p>

<h3><a name="Ftplet-Ftplet"></a>Ftplet</h3>

<p>There will be only one instance of Ftplet. During startup the Ftplets will be \
initialized. The initialization sequence is same as the Ftplet sequence in the \
configuration. Then all notification methods will be called and when the FtpServer \
goes down, the Ftplet will be destroyed. The following method describes all the \
notification methods.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> onConnect </td>
<td class='confluenceTd'> Client connect notification method. This is the first \
method FtpServer will call. If it returns SKIP, IP restriction check, connection \
limit check will not be performed and the server will not send the welcome message \
(220). </td> </tr>
<tr>
<td class='confluenceTd'> onDisconnect </td>
<td class='confluenceTd'> Client disconnect notification method. This is the last \
method FtpServer will call. Whatever it returns, the client connection will be \
closed. </td> </tr>
<tr>
<td class='confluenceTd'> beforeCommand </td>
<td class='confluenceTd'> Called before the server invoke the command.  </td>
</tr>
<tr>
<td class='confluenceTd'> afterCommand </td>
<td class='confluenceTd'> Called after the server as invoked the command. </td>
</tr>
</tbody></table>
</div>


<h3><a name="Ftplet-DefaultFtplet"></a>DefaultFtplet</h3>

<p>DefaultFtplet provides some convenience methods for common FTP commands. Users can \
easily extend the DefaultFtplet class and choose what methods to override and handle. \
</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> onLogin </td>
<td class='confluenceTd'> Client login notification method. This will be called after \
the user authentication. In this case the FtpServer has already sent the login OK \
(230) reply. This is called during FTP PASS request. The FTP session will be \
disconnected in the return value is FtpletResult.DISCONNECT. </td> </tr>
<tr>
<td class='confluenceTd'> onDeleteStart </td>
<td class='confluenceTd'> Before file deletion this method will be called. Before \
this FtpServer will not check anything like file existence or permission. The \
requested file name can be get from request argument. We can get the file object from \
the request file system view. This is called in DELE FTP command. The method should \
send some responses (like 250, 450, 550) in case of SKIP return value. In this case, \
the server will skip the command processing and the ftplet has to send appropriate \
response values. </td> </tr>
<tr>
<td class='confluenceTd'> onDeleteEnd </td>
<td class='confluenceTd'> This method will be called after the file deletion, \
successful or not. In this case the FtpServer has already sent the reply message. \
This is called in DELE FTP command. </td> </tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> This method will be called before the file upload. The file \
name can be get from the request argument. We can get the data input stream from \
request. This will be called before the permission check. This is called during STOR \
command. If the method returns SKIP, it has to send responses before and after \
processing. For example, before opening the data input stream, the method has to \
notify the client with a response code 150. Similarly, after the data transfer, the \
method has to notify the client with a response code 226. In case of any error, the \
method should send different response codes like 450, 425, 426, 551. </td> </tr>
<tr>
<td class='confluenceTd'> onUploadEnd </td>
<td class='confluenceTd'> This notification method will be called to indicate that \
the file transfer is successful and the server has send the replies. In case of any \
error this method will not be called. This is called in STOR command. </td> </tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> This is file download request notification method called \
during RETR command. This will be called before the file download. We can get the \
file name argument from request. Similarly, the data output stream can be get from \
the request. This will be called before the file existance and permissoin check. If \
the method returns SKIP, it has to send responses before and after processing. For \
example, before opening the data output stream, the method has to notify the client \
with a response code 150. Similarly, after the data transfer, the method has to \
notify the client with a response code 226. In case of any error, the method should \
send different response codes like 450, 425, 426, 551. </td> </tr>
<tr>
<td class='confluenceTd'> onDownloadEnd </td>
<td class='confluenceTd'> This notification method will be called to indicate that \
the file transfer is successful and the server has send the replies in RETR command.  \
</td> </tr>
<tr>
<td class='confluenceTd'> onRmdirStart </td>
<td class='confluenceTd'> Before directory deletion this method will be called during \
RMD command. Before this FtpServer will not check anything like directory existance \
or permission. The requested directory name can be get from request argument. If the \
method returns the SKIP, it has to send appropriate response codes to clients like \
250, 450,                              550. </td> </tr>
<tr>
<td class='confluenceTd'> onRmdirEnd </td>
<td class='confluenceTd'> This method will be called after the invocation of the RMD \
command. In this case the FtpServer has already sent the reply message. </td> </tr>
<tr>
<td class='confluenceTd'> onMkdirStart </td>
<td class='confluenceTd'> Before directory creation this method will be called during \
MKD command. Before this FtpServer will not check anything like directory existance \
or permission. The requested directory name can be get from request argument. If it \
returns SKIP, it has to send appropriate response codes to clients like 250, 550. \
</td> </tr>
<tr>
<td class='confluenceTd'> onMkdirEnd </td>
<td class='confluenceTd'> This method will be called if the directory creation is \
successful in MKD command. In this case the FtpServer has already sent the reply \
message.  </td> </tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> This is file append request notification method called in \
APPE command. The file name can be get from the request argument. We can get the data \
input stream from request. This will be called before the permission check. If the \
method returns SKIP, it has to send responses before and after processing. For \
example, before opening the data input stream, the method has to notify the client \
with a response code 150. Similarly, after the data transfer, the method has to \
notify the client with a response                              code 226. In case of \
any error, the method should send different response codes like 450, 425, 426, 551. \
</td> </tr>
<tr>
<td class='confluenceTd'> onAppendEnd </td>
<td class='confluenceTd'> This is file append success notification method called in \
APPE command.  </td> </tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> This is unique file create request notification method \
called in STOU command. We can get the data input stream from request. This will be \
called before the permission check. If the method returns SKIP, it has to send \
responses before and after processing. For example, before opening the data input \
stream, the method has                              to notify the client with a \
response code 150. Similarly, after the data transfer, the method has to notify the \
client with a response code 226. In case of any error, the method should send \
different response codes like 450, 425, 426, 551. </td> </tr>
<tr>
<td class='confluenceTd'> onUploadUniqueEnd </td>
<td class='confluenceTd'> This is unique file create success notification method \
called in STOU command. This notification method will be called to indicate the the \
server has send the replies.  </td> </tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> This is file rename start notification method called in \
RNTO command. This will be called before the file existance or permission check. The \
"rename from" file object can be get from request object. If it returns SKIP, it has \
to send appropriate response codes like 503, 553, 250. </td> </tr>
<tr>
<td class='confluenceTd'> onRenameEnd </td>
<td class='confluenceTd'> This is file rename success notification method called in \
RNFR command. This will be called before the file existance or permission check. The \
"rename from" file object an be get from request object. This notification method \
will be called after the invocation of the RNTO command and the server has send the \
reply message.  </td> </tr>
<tr>
<td class='confluenceTd'> onSite </td>
<td class='confluenceTd'> This is SITE command start notification method. It gives a \
chance to implement custom SITE command. If this method returns SKIP or DISCONNECT, \
the existing SITE commands will not be executed. </td> </tr>
</tbody></table>
</div>


<h3><a name="Ftplet-ResponseCodes"></a>Response Codes</h3>

<p>This section gives an overview on different response codes which might be useful \
in developing custom ftplet. These commands might be used when the ftplet method \
return value is SKIP.</p> <div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Method </th>
<th class='confluenceTh'> Response Code </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> onConnect </td>
<td class='confluenceTd'> 220 </td>
<td class='confluenceTd'> Service ready for new user. </td>
</tr>
<tr>
<td class='confluenceTd'> onConnect </td>
<td class='confluenceTd'> 530 </td>
<td class='confluenceTd'> No server access from the IP. </td>
</tr>
<tr>
<td class='confluenceTd'> onConnect </td>
<td class='confluenceTd'> 530 </td>
<td class='confluenceTd'> Maximum server connection has been reached. </td>
</tr>
<tr>
<td class='confluenceTd'> onDisconnect </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onLogin </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onDeleteStart </td>
<td class='confluenceTd'> 250 </td>
<td class='confluenceTd'> Requested file action okay </td>
</tr>
<tr>
<td class='confluenceTd'> onDeleteStart </td>
<td class='confluenceTd'> 450 </td>
<td class='confluenceTd'> No permission to delete. </td>
</tr>
<tr>
<td class='confluenceTd'> onDeleteStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Not a valid file. </td>
</tr>
<tr>
<td class='confluenceTd'> onDeleteStart </td>
<td class='confluenceTd'> 450 </td>
<td class='confluenceTd'> Can't delete file. </td>
</tr>
<tr>
<td class='confluenceTd'> onDeleteEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 150 </td>
<td class='confluenceTd'> File status okay; about to open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 226 </td>
<td class='confluenceTd'> Transfer complete. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Invalid path. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 425 </td>
<td class='confluenceTd'> Can't open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 426 </td>
<td class='confluenceTd'> Data connection error. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadStart </td>
<td class='confluenceTd'> 551 </td>
<td class='confluenceTd'> Error on output file. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 150 </td>
<td class='confluenceTd'> File status okay; about to open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 226 </td>
<td class='confluenceTd'> Transfer complete. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> No such file or directory. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Not a plain file. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 425 </td>
<td class='confluenceTd'> Can't open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 426 </td>
<td class='confluenceTd'> Data connection error. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadStart </td>
<td class='confluenceTd'> 551 </td>
<td class='confluenceTd'> Error on input file. </td>
</tr>
<tr>
<td class='confluenceTd'> onDownloadEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onRmdirStart </td>
<td class='confluenceTd'> 250 </td>
<td class='confluenceTd'> Directory removed. </td>
</tr>
<tr>
<td class='confluenceTd'> onRmdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Not a valid directory. </td>
</tr>
<tr>
<td class='confluenceTd'> onRmdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onRmdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Can't remove directory. </td>
</tr>
<tr>
<td class='confluenceTd'> onRmdirEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onMkdirStart </td>
<td class='confluenceTd'> 250 </td>
<td class='confluenceTd'> Directory created. </td>
</tr>
<tr>
<td class='confluenceTd'> onMkdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Not a valid file. </td>
</tr>
<tr>
<td class='confluenceTd'> onMkdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Permission denied </td>
</tr>
<tr>
<td class='confluenceTd'> onMkdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Directory already exists. </td>
</tr>
<tr>
<td class='confluenceTd'> onMkdirStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Can't create directory. </td>
</tr>
<tr>
<td class='confluenceTd'> onMkdirEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 150 </td>
<td class='confluenceTd'> File status okay; about to open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 226 </td>
<td class='confluenceTd'> Transfer complete. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Not a plain file. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 425 </td>
<td class='confluenceTd'> Can't open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 426 </td>
<td class='confluenceTd'> Data connection error. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendStart </td>
<td class='confluenceTd'> 551 </td>
<td class='confluenceTd'> Error on output file. </td>
</tr>
<tr>
<td class='confluenceTd'> onAppendEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 150 </td>
<td class='confluenceTd'> File status okay; about to open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 250 </td>
<td class='confluenceTd'> filename: Transfer started. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 226 </td>
<td class='confluenceTd'> filename: Transfer complete. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Unique file name error. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 550 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 425 </td>
<td class='confluenceTd'> Can't open data connection. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 426 </td>
<td class='confluenceTd'> Data connection error. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueStart </td>
<td class='confluenceTd'> 551 </td>
<td class='confluenceTd'> Error on output file. </td>
</tr>
<tr>
<td class='confluenceTd'> onUploadUniqueEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> 250 </td>
<td class='confluenceTd'> Requested file action okay, file renamed. </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> 503 </td>
<td class='confluenceTd'> Can't find the file which has to be renamed. </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> 553 </td>
<td class='confluenceTd'> Not a valid file name. </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> 553 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> 553 </td>
<td class='confluenceTd'> No such file or directory. </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameStart </td>
<td class='confluenceTd'> 553 </td>
<td class='confluenceTd'> Can't rename file. </td>
</tr>
<tr>
<td class='confluenceTd'> onRenameEnd </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
<td class='confluenceTd'> <br class="atl-forced-newline" /> </td>
</tr>
<tr>
<td class='confluenceTd'> onSite </td>
<td class='confluenceTd'> 200 </td>
<td class='confluenceTd'> Command SITE okay. </td>
</tr>
<tr>
<td class='confluenceTd'> onSite </td>
<td class='confluenceTd'> 530 </td>
<td class='confluenceTd'> Permission denied. </td>
</tr>
<tr>
<td class='confluenceTd'> onSite </td>
<td class='confluenceTd'> 502 </td>
<td class='confluenceTd'> Not implemented. </td>
</tr>
<tr>
<td class='confluenceTd'> onSite </td>
<td class='confluenceTd'> 500 </td>
<td class='confluenceTd'> Execution failed. </td>
</tr>
</tbody></table>
</div>

<h3><a name="Ftplet-Configuration"></a>Configuration</h3>

<p>Ftplet will get the Ftplet specific configuration as the init() method \
argument.</p>

<h3><a name="Ftplet-Implementation"></a>Implementation</h3>

<p>Ftplets are regular POJOs. If running the server as embedded they can be added to \
the FtpletContainer as normal instances of the object. If using the XML \
configuration, they are configured and Spring beans within the <em>ftplets</em> \
element. Here's an example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent \
panelContent"> <pre class="code-java">
&lt;ftplets&gt; 
  &lt;ftplet name=<span class="code-quote">"ftplet1"</span>&gt; 
    &lt;beans:bean class=<span \
                class="code-quote">"org.apache.ftpserver.examples.MyFtplet"</span>&gt; \
                
      &lt;beans:property name=<span class="code-quote">"foo"</span> value=<span \
class="code-quote">"123"</span> /&gt;   &lt;/beans:bean&gt; 
  &lt;/ftplet&gt; 
&lt;/ftplets&gt;
</pre>
</div></div>

<h2><a name="Ftplet-Deployment"></a>Deployment</h2>

<p>The Ftplet must be added to Apache FtpServer classpath so that the Ftplet can be \
loaded. There are three ways you can do that.</p> <ol>
	<li>Modify your system CLASSPATH environment variable to include your ftplet \
classes.</li>  <li>Copy your ftplet class files (unpacked) in the common/classes \
bdirectory of the FtpServer installation.</li>  <li>Place a jar file containing the \
custom ftplet class files in the common/lib subdirectory of the FtpServer \
installation.</li> </ol>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action" \
class="grey">Change Notification Preferences</a>  </div>
        <a href="https://cwiki.apache.org/confluence/display/FTPSERVER/Ftplet">View \
Online</a>  |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=82753&revisedVersion=7&originalVersion=6">View \
Changes</a>  |
        <a href="https://cwiki.apache.org/confluence/display/FTPSERVER/Ftplet?showComments=true&amp;showCommentArea=true#addcomment">Add \
Comment</a>  </div>
</div>
</div>
</div>
</div>
</body>
</html>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic