熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

一個相當經典的RMI實例源代碼及詳細說明

2013-11-23 20:06:48  來源: Java開源技術 

  RMI技術
  下面以一個例子說明怎麼使用RMI技術這個例子演示了怎樣將一個文件上傳到服務器和怎樣將一個文件從服務器上下載下來
  使用RMI技術共有個步驟要走: ()定義和實現遠端接口中的參數 () 定義和實現遠端接口 () 編寫服務端代碼 ()編寫客戶端代碼 ()生成stub和skeltion 並將stub打包到客戶端jar中將skeltion打包到服務端jar中 ()啟動rmiregistry 並將服務注冊到rmiregistry中然後運行代碼下面就這六個方面說明rmi技術
  
  定義和實現遠端接口中的參數
  ()定義遠端接口中的參數
  每一個遠端接口中的參數都必須是可序列化的那麼如何定義一個序列化的接口呢簡單只需從javaioSerializable繼承即可如下所示
  import javaioSerializable;
  
  public interface FileInformation extends Serializable {
    String getName();
    byte[] getContent();
    void  setInformation(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(FileInformation fileInof) 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 UnicastRemoteObject implements LoadFile {
    private String currentDir= null ;
    // this contruction is needed  
    public LoadFileService() throws RemoteException {
     super();
    }
  
    public void setCurrentDir(String currentDir){
      thiscurrentDir = currentDir ;
    }
  
    public void upLoadFile(FileInformation fileInfo) 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 content is 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() );
       
  //創建一個服務對象
        LoadFileService server = new LoadFileService();
        serversetCurrentDir(c:\\rmiexample);
       
        //將服務對象注冊到rmi注冊服務器上而不是其他服務器
  //(因為LoadFileService extends UnicastRemoteObject)
        Namingrebind(//:/LoadFileServer server);
     }catch(Exception ex){
       Systemoutprintln(exgetLocalizedMessage());
       exprintStackTrace();
     }
   }
  }
  
  注意將對象注冊以後不可關閉服務對象
  
  編寫客戶端代碼
  客戶端代碼需要兩個步驟
  ()根據服務的名稱查找服務對象
  ()調用服務服務對象對應的方法完成工作
  在這個例子中我們從客戶端上傳一個文件到服務器並將服務器的一個文件下載下來
  代碼如下
   import javaioIOExcep
From:http://tw.wingwit.com/Article/program/Java/ky/201311/27945.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.