使用文件传输API,通过现有的MQ网络发送文件到远程服务器,包括以下步骤:
创建IMqLoginer接口的实现类对象,一般都使用JaasLoginerImpl作为实现。接着调用该接口的login方法,登录到指定的服务器,该服务器将作为客户端发送器所连接的服务器,发送文件的时候会先将文件上传到该服务器,再由该服务器发送到远程的目的服务器。创建 IMqLoginer接口的实现类对象的时候必须将
“admin”
作为用户名和并提供其密码,因为 AMQ 的文件传输功能目前限制只能由
“admin”
用户使用。
将IMqLoginer接口的实现类对象作为参数创建FileTransporterObjectFactory类的对象,并使用该对象工厂创建实现了IFileSender接口的客户端文件发送器对象。
创建发送信息对象,指定文件分成多少块同时传输、文件的目的服务器的路由名、文件的备注、文件在本地机器的路径四个参数。
假如在要监听文件发送器的状态转换过程,显示文件的发送进度,已发送字节数等信息,可以在调用IFileSender接口的send方法之前向文件发送器注册监听器,监听文件发送器的状态转换过程。
调用IFileSender接口的send方法开始发送文件,调用该方法之后,调用方法的线程将会阻塞,直到文件发送完毕、取消了发送或者发送文件时出现异常。
判断文件是否已经发送完毕或者是否在发送过程中出现了异常。
登出服务器。
以下代码演示了如何使用文件传输API,通过现有的MQ网络发送文件到远程服务器:
public static void main(String[] args) throws Exception {
//创建登陆器对象,在创建对象时指定要登录的服务器的IP地址,端口号,用户名和密码
//注意:必须将“admin”作为用户名和并提供其密码,因为 AMQ 的文件传输功能目前
//限制只能由“admin”用户使用。
IMqLoginer loginer = new JaasLoginerImpl("localhost", 4888, "admin", "admin");
loginer.login();
//创建对象工厂,并创建文件发送器对象。
FileTransporterObjectFactory factory = new FileTransporterObjectFactory(loginer);
IFileSender sender = factory.createClientFileSender();
//指定文件分成多少块同时进行传输,每一块由一个线程传输。
int sendingThreadsNum = 5;
//指定文件的目的服务器的路由名。
String destTarget = "RouterB";
//指定文件的备注。
String remark = "This is a test file.";
//指定要发送的文件在本地机器的路径。
String sendingFilePath = "F:\\jdk-1_5_0_07-windows-i586-p.rar";
//使用以上的参数创建发送信息对象。
FileSendingInfo info = new FileSendingInfo(sendingThreadsNum, destTarget, remark, sendingFilePath);
//向文件发送器中加入监听器,监听发送器的状态转换。
sender.addFileSenderListener(new ClientFileSenderListener(sendingFilePath));
//启动一个新的线程,用于接收用户输入取消发送,因为主线程调用send方法之后
//将会处于阻塞状态。在新启动的线程中调用IFileSender的cancelCurrentSending方法
//取消发送。
CancelSendingThread cancelThread = new CancelSendingThread(sender, sendingFilePath);
cancelThread.start();
//开始发送文件,并得到send返回之后的发送结果,判断发送是否出现异常了。
//还可以判断文件是否已经发送完毕,假如没有发送完毕可以从发送结果中取得
//该文件的UUID,下次继续将该文件发送到服务器上的时候需要提供该UUID。
//假如要继续发送未发送完的文件,这里调用的是continueSend方法,其他过程一样。
FileSendingResult result = sender.send(info);
if (result.getSendFileException() != null) {
throw new Exception("Send file failed.", result.getSendFileException());
}
//登出服务器。
loginer.logout();
}
文件发送器的监听器代码:
class ClientFileSenderListener implements IFileSenderListener {
//发送的文件的路径。
private final String sendingFilePath;
//打印文件发送进度等信息的线程。
private PrintSendingStateThread printThread;
private ClientFileSenderListener(String sendingFilePath) {
this.sendingFilePath = sendingFilePath;
}
/**
* 当发送器准备完毕,开始发送文件的时候会调用监听器的该方法。
* 调用该方法之前,发送器已经处于STATE_SENDING状态。
* @param sender
* 发生该状态变化的发送器。
*/
public void onAfterSendingStarted(IFileSender sender) {
//启动打印文件发送状态线程,在线程中调用IFileSender的getCurrentSendingFileSize
//getFileSendedSize等方法显示文件发送进度等信息。
this.printThread = new PrintSendingStateThread(sender, sendingFilePath);
this.printThread.start();
//进行日志记录等代码
...
}
/**
* 当发送器已经停止了发送文件,会调用监听器的该方法。
* 调用该方法的时候,发送器已经处于STATE_IDLE状态。
* @param sender
* 发生该状态变化的发送器。
*/
public void onAfterSendingStoped(IFileSender sender) {
//停止打印发送状态线程。
synchronized (this.printThread.getPrintThreadSemaphore()) {
this.printThread.getPrintThreadSemaphore().notifyAll();
}
//进行日志记录等代码
...
}
/**
* 当发送器准备停止发送文件,在停止之前会调用监听器的该方法。
* 调用该方法的时候,发送器还不是处于STATE_IDLE状态。
* @param sender
* 发生该状态变化的发送器。
*/
public void onBeforeSendingStoped(IFileSender sender) {
//可以在该方法中显示文件发送器停止发送之前,总共发送了文件的多少字节
//发送进度等信息。或者进行日志记录等。
}
}