FtpServer是基于MINA的一个微型的FTP Server的实现,据说可以很好的集成到其他程序中,提供ftp服务
最近在看mina,顺便想找个大一点儿的例子来看看MINA是如何使用的。就找到了这个FTP实现,看了下代码,感觉还是不错的,决定写些东西记录自己的想法。先从最简单的开始。
不愧是MINA下的项目,很多地方都可以看到MINA的气息
和MINA 其他程序一样,ftp业务逻辑封装到FtpHandler中。代码如下:
FtpHandler
public interface FtpHandler {
void init(FtpServerContext context, Listener listener) throws Exception;
/**
* Invoked from an I/O processor thread when a new connection has been
* created. Because this method is supposed to be called from the same
* thread that handles I/O of multiple sessions, please implement this
* method to perform tasks that consumes minimal amount of time such as
* socket parameter and user-defined session attribute initialization.
*/
void sessionCreated(FtpIoSession session) throws Exception;
/**
* Invoked when a connection has been opened. This method is invoked after
* {@link #sessionCreated(IoSession)}. The biggest difference from
* {@link #sessionCreated(IoSession)} is that it's invoked from other thread
* than an I/O processor thread once thread modesl is configured properly.
*/
void sessionOpened(FtpIoSession session) throws Exception;
/**
* Invoked when a connection is closed.
*/
void sessionClosed(FtpIoSession session) throws Exception;
/**
* Invoked with the related {@link IdleStatus} when a connection becomes
* idle. This method is not invoked if the transport type is UDP; it's a
* known bug, and will be fixed in 2.0.
*/
void sessionIdle(FtpIoSession session, IdleStatus status) throws Exception;
/**
* Invoked when any exception is thrown by user {@link IoHandler}
* implementation or by MINA. If <code>cause</code> is instanceof
* {@link IOException}, MINA will close the connection automatically.
*/
void exceptionCaught(FtpIoSession session, Throwable cause)
throws Exception;
/**
* Invoked when a message is received.
*/
void messageReceived(FtpIoSession session, FtpRequest request)
throws Exception;
/**
* Invoked when a message written by {@link IoSession#write(Object)} is sent
* out.
*/
void messageSent(FtpIoSession session, FtpReply reply) throws Exception;
}
void init(FtpServerContext context, Listener listener) throws Exception;
/**
* Invoked from an I/O processor thread when a new connection has been
* created. Because this method is supposed to be called from the same
* thread that handles I/O of multiple sessions, please implement this
* method to perform tasks that consumes minimal amount of time such as
* socket parameter and user-defined session attribute initialization.
*/
void sessionCreated(FtpIoSession session) throws Exception;
/**
* Invoked when a connection has been opened. This method is invoked after
* {@link #sessionCreated(IoSession)}. The biggest difference from
* {@link #sessionCreated(IoSession)} is that it's invoked from other thread
* than an I/O processor thread once thread modesl is configured properly.
*/
void sessionOpened(FtpIoSession session) throws Exception;
/**
* Invoked when a connection is closed.
*/
void sessionClosed(FtpIoSession session) throws Exception;
/**
* Invoked with the related {@link IdleStatus} when a connection becomes
* idle. This method is not invoked if the transport type is UDP; it's a
* known bug, and will be fixed in 2.0.
*/
void sessionIdle(FtpIoSession session, IdleStatus status) throws Exception;
/**
* Invoked when any exception is thrown by user {@link IoHandler}
* implementation or by MINA. If <code>cause</code> is instanceof
* {@link IOException}, MINA will close the connection automatically.
*/
void exceptionCaught(FtpIoSession session, Throwable cause)
throws Exception;
/**
* Invoked when a message is received.
*/
void messageReceived(FtpIoSession session, FtpRequest request)
throws Exception;
/**
* Invoked when a message written by {@link IoSession#write(Object)} is sent
* out.
*/
void messageSent(FtpIoSession session, FtpReply reply) throws Exception;
}
简直和MINA 中的IoHandler一模一样,就是把原来的session换成了FtpIoSession,可能作者不想让MINA太多的影响自己,所以把自己完全包装了一遍,必要的时候就Adapter一下,代码如下
写道
public class FtpHandlerAdapter implements IoHandler {
private FtpServerContext context;
private FtpHandler ftpHandler;
public FtpHandlerAdapter(FtpServerContext context, FtpHandler ftpHandler) {
this.context = context;
this.ftpHandler = ftpHandler;
}
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.exceptionCaught(ftpSession, cause);
}
public void messageReceived(IoSession session, Object message)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
FtpRequest request = new FtpRequestImpl(message.toString());
ftpHandler.messageReceived(ftpSession, request);
}
public void messageSent(IoSession session, Object message) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.messageSent(ftpSession, (FtpReply) message);
}
public void sessionClosed(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionClosed(ftpSession);
}
public void sessionCreated(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionCreated(ftpSession);
}
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionIdle(ftpSession, status);
}
public void sessionOpened(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionOpened(ftpSession);
}
public FtpHandler getFtpHandler() {
return ftpHandler;
}
public void setFtpHandler(FtpHandler handler) {
this.ftpHandler = handler;
}
}
private FtpServerContext context;
private FtpHandler ftpHandler;
public FtpHandlerAdapter(FtpServerContext context, FtpHandler ftpHandler) {
this.context = context;
this.ftpHandler = ftpHandler;
}
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.exceptionCaught(ftpSession, cause);
}
public void messageReceived(IoSession session, Object message)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
FtpRequest request = new FtpRequestImpl(message.toString());
ftpHandler.messageReceived(ftpSession, request);
}
public void messageSent(IoSession session, Object message) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.messageSent(ftpSession, (FtpReply) message);
}
public void sessionClosed(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionClosed(ftpSession);
}
public void sessionCreated(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionCreated(ftpSession);
}
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionIdle(ftpSession, status);
}
public void sessionOpened(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionOpened(ftpSession);
}
public FtpHandler getFtpHandler() {
return ftpHandler;
}
public void setFtpHandler(FtpHandler handler) {
this.ftpHandler = handler;
}
}
在FtpHandlerAdapter中,不仅adapt了FtpHandler,还完成了IoSession到FtpSession 的封装。
未完待续