RMI技术 下面以一个例子说明怎么使用RMI技术这个例子演示了怎样将一个文件上传到服务器和怎样将一个文件从服务器上下载下来 使用RMI技术共有个步骤要走: ()定义和实现远端接口中的参数 () 定义和实现远端接口 () 编写服务端代码 ()编写客户端代码 ()生成stub和skeltion 并将stub打包到客户端jar中将skeltion打包到服务端jar中 ()启动rmiregistry 并将服务注册到rmiregistry中然后运行代码下面就这六个方面说明rmi技术 定义和实现远端接口中的参数 ()定义远端接口中的参数 每一个远端接口中的参数都必须是可序列化的那么如何定义一个序列化的接口呢简单只需从javaioSerializable继承即可如下所示 import javaioSerializable; public interface FileInformation extends Serializable { StringgetName(); byte[]getContent(); voidsetInformation(String name byte[] content); }; ()实现远端接口中的参数 实现远端接口中的参数的接口跟与实现其他任何接口没什么不一样的地方如下所示 public class FileInformationSev implements FileInformation { private String name = null ; private byte[] content = null ; public String getName() { return name ; } public byte[] getContent() { return content; } public void setInformation(String name byte[] content) { thisname = name ; ntent = content ; } } 那么为什么要序列化远端接口中的参数(返回值) ?这是因为需要将客户端的对象(参数)转化成byte stream通过网络协议传输到服务端再还原成服务端的对象进行调用或者是需要将服务端的对象(返回值)转化成byte stream通过网络协议传输到服务端再还原成客户端的对象进行调用 在 jdk中 javalang包和javautil包下的类都已经实现了序列化直接可以用在远程接口中作参数或返回值所有的基本类型也可以直接用在远程接口中作参数或返回值 定义和实现远端接口 ()定义远端接口 远端接口必须从javarmiRemote继承远端接口中的方法如果要throw异常这个异常必须是javarmiRemoteException(或javarmiRemoteException的子类)否则这个异常就不能被返回到客户端Example如下 import javarmiRemote; import javarmiRemoteException; public interface LoadFile extends Remote { void upLoadFile(FileInformationfileInof) throws RemoteException; FileInformation downLoadFile(String filename) throws RemoteException ; } ()实现远端接口 实现远端接口比较容易跟其他接口的实现没有什么区别如下所示 import javarmiRemote; import javarmiRemoteException; import javaioIOException; import javaioFile; import javaioBufferedInputStream; import javaioFileInputStream; import javaioBufferedOutputStream; import javaioFileOutputStream; import javarmiserverUnicastRemoteObject; public class LoadFileService extends UnicastRemoteObjectimplements LoadFile { private StringcurrentDir= null ; // this contruction is needed public LoadFileService() throws RemoteException { super(); } publicvoidsetCurrentDir(String currentDir){ thiscurrentDir = currentDir ; } public void upLoadFile(FileInformationfileInfo) throws RemoteException{ BufferedOutputStream output = null ; try{ // check paramter if(fileInfo == null ){ throw new RemoteException(the paramter is null ); } //check fileName and content String fileName = fileInfogetName() ; byte [] content = fileInfogetContent() ; if(fileName == null || content == null ){ throw new RemoteException(the file or the contentis null ); } //create file String filePath = thiscurrentDir + \\ + fileName ; File file = new File(filePath); if(!fileexists()){ filecreateNewFile(); } //save the content to the file output = new BufferedOutputStream(new FileOutputStream(file)); outputwrite(content); }catch(RemoteException ex){ throw ex ; }catch(Exception ex){ throw new RemoteException(exgetLocalizedMessage()); }finally{ if(output != null ){ try{ outputclose(); output = null ; }catch(Exception ex){ } } } } public FileInformation downLoadFile(String fileName) throws RemoteException { FileInformation fileInfo = null ; BufferedInputStream input = null ; try{ // check paramter if(fileName == null){ throw new RemoteException(the paramter is null ); } // get path String filePath = thiscurrentDir + \\ + fileName ; File file = new File(filePath); if(!fileexists()){ throw new RemoteException(the file whose name is + fileName + not existed ); } // get content byte[] content = new byte[(int)filelength()]; input = new BufferedInputStream(new FileInputStream(file)); inputread(content); // set file name and content to fileInfo fileInfo = new FileInformationSev(); fileInfosetInformation(fileName content); }catch(RemoteException ex){ throw ex ; }catch(Exception ex){ throw new RemoteException(exgetLocalizedMessage()); }finally{ if(input != null ){ try{ inputclose(); input = null ; }catch(Exception ex){ } } } return fileInfo ; } } 编写服务端代码 服务端代码主要有个步骤 ()加载安全管理器 ()创建一个服务对象 ()将这个服务对象注册到命名服务上
import javarmiRMISecurityManager; import javarmiNaming; public class RMIServer { public static void main(String[] args) { try{ //加载安全管理器 SystemsetSecurityManager(new RMISecurityManager() ); //创建一个服务对象 LoadFileServiceserver = new LoadFileService(); serversetCurrentDir(c:\\rmiexample); //将服务对象注册到rmi注册服务器上而不是其他服务器 //(因为LoadFileService extends UnicastRemoteObject) Namingrebind(//:/LoadFileServer server); }catch(Exception ex){ Systemoutprintln(exgetLocalizedMessage()); exprintStackTrace(); } } } 注意将对象注册以后不可关闭服务对象 编写客户端代码 客户端代码需要两个步骤 ()根据服务的名称查找服务对象 ()调用服务服务对象对应的方法完成工作 在这个例子中我们从客户端上传一个文件到服务器并将服务器的一个文件下载下来 代码如下 import javaioIOExcep |