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

通過E-mail 共享Java 對象

2022-06-13   來源: Java核心技術 

  JDK的新功能序列化接口(Serializableinterface)簡化了對象持久化(Persistence)的實現以下介紹如何通過SMTPEmail將對象傳送給另一個用戶
  摘要一些應用程序需要以一種非實時的方式(例如旅行指南錯誤報告(bugreport) 時間表(timesheet)等)和其余用戶共享對象Java語言開發工具包(JDK)版提供了一 個重要的功能:javaioSerializable接口該技術能讓你知道如何序列化一個對象然 後用email傳給其它用戶
  對象持久化和用戶間對象共享是許多商業解決方案的基礎例如一個公司可以用從本公司網址啟動的Applet來完成一個時間表的制作同樣該公司也可以提供象具有開支報告旅行指 南錯誤報告(bugreport)等功能的Applet在這些情況下從Applet的使用者獲得的數據需要和負責薪水付款旅行房間預訂的人們共享執行這些職能的人們可能分布在不同的 城市和國家可能工作在不同的時區不能希望每個工作人員都能象貓頭鷹一樣在晚上工作以填寫這樣的表格相同的信息也不應該重新輸入因此能夠存儲並且把這些相關對象傳 送到商業應用中是這些applet有別於其它applet的優勢
  目前已經有許多方法能實現對象的持久化例如使用對象數據庫和磁盤文件同樣的也有許多辦法可以共享對象例如將數據寫入一個套接字或者實現一個符合CORBASOM的模 型以上這幾種方案均有自己的優點當你設計你的商業解決方案時需要認真地考慮這些方案但是還有一種開銷不大但可靠的方法它使用Internet和Intranet用戶能夠獲取的 技術服務在世界范圍傳送對象的拷貝它就是簡單郵件傳輸協議SMTP
  用Email發送Java對象
  存儲和保存對象的一個簡單方法是將對象序列化而後用Email將它發送給別的用戶這種 方法有以下優點:
  發送的計算機或NC(網絡計算機)無需硬盤空間
  使用現有的系統傳送排隊發送對象
  允許用戶使用最喜歡的郵件客戶程序來接受郵件
  提供簡單的機制將同一對象的拷貝分發給許多人
  這種方法也有不足之處:
  郵件的傳送可能因為Email主機的關機而被較長時間地延遲所有的主機都可能出現這 種情況Email服務器的錯誤恢復優先級通常比數據庫服務器低
  郵件的傳送不能得到保證在你的Email服務器通知你郵件沒有發出時你不得不重新 發送郵件
  Email服務器和POP客戶程序的功能不足以處理大量交易信息
  這些不足和你使用的應用程序有關對於很多商業解決方案這些不足並不重要作為一個設計人員你工作的一部分就是在全面考慮價格性能和需求的情況下確定系統的最佳整體結構
  使用Java傳送對象的四個步驟:
  Applet必須依次以下面所列出的四個步驟傳送Java對象:
  序列化有關對象
  發送時選擇Base編碼方式對序列化對象編碼(RFC
  與一個SMTP服務器連接
  將該對象傳送到這個SMTP服務器
  下面將介紹如何用Email發送一個假設的臭蟲報告到公司的質量保證部門
  將對象序列化
  JDK提供的一個奇妙的機制javaioSerializable接口能夠序列化並且重建對象 這個接口能使用存儲對象(writeObject())和恢復對象(readObject())方法函數在很多 情況下使用這個接口很方便只需實現並且調用這兩個方法函數
  以下的代碼定義了一個簡單的BugReport對象它實現了最簡單的序列化接口
  
   import javaIo*;
   public class BugReport implements Serializable {
   private Float m_SoftwareVersion; // version number from HelpAbout eg
   private String m_ErrorDescription; // Description of error
   private int m_Severity; // =System unusable =Minor Aesthetic defect
  
   public BugReport (Float SoftwareVersion String ErrorDescription int Severity) {
   m_SoftwareVersion = SoftwareVersion;
   m_ErrorDesctiption = ErrorDescription;
   m_Severity = Severity;
   }
  
   public BugReport () {} // for reconstituting serialized objects
  
   public void save (OutputStream os)
   throws IOException {
   try {
   ObjectOutputStream o = new ObjectOutputStream(os);
   owriteObject(this);
   oflush();
   }
   catch (IOException e) {throw e;}
   }
  
   public BugReport restore (InputStream is)
   throws IOException ClassNotFoundException {
   BugReport RestoredBugReport = null;
   try {
   ObjectInputStream o = new ObjectInputStream(is);
   RestoredBugReport = (BugReport)oreadObject();
   }
   catch (IOException e) {throw e;}
   catch (ClassNotFoundException e) {throw e;}
   return RestoredBugReport;
   }
   } 
  使用import語句引入I/O包包括序列化接口
  定義類中的成員變量並指出該類實現了序列化接口
  提供一個簡單的構造函數
  一個空的構造函數這個構造函數在重建序列化對象時使用見以下的例子
  定義一個方法函數它把對象寫入一個已經打開了的ObjectOutputStream這個方 法函數首先創建一個ObjectOutputStream對象然後調用writeObject方法函數最後在 函數返回前顯式清空輸出緩沖區
  定義一個方法函數它從一個打開了的InputStream中讀入一個BugReport對象注 意如果輸入流中下一個對象和正在讀入對象的類型不一致時readObject()將會拋出一 個異常
  使用BugReport對象相當簡單譬如我們想要創建一個新的BugReport對象並且把它存入 一個文件我們會用到以下代碼:
  
   import javaio*;
  
  
   BugReport bug = new BugReport( Crashes when spell checker invoked );
   FileOUtputStream os = new FileOutputStream(MyBugtest);
   bugsave(os); 
  很簡單對嗎?當然一旦對象已經被序列化沒有人能阻止你繼續操縱對象的狀態上一 個例子中包涵了一個在被寫入磁盤時已經存在對象的拷貝因此你必須要十分謹慎以防 在對對象做出所有的修改之後沒有序列化對象從而丟失了對象的狀態修改信息
  以下是怎樣恢復一個對象的拷貝:
   import javaio*
  
  
   FileInputStream fis = new FileInputStream(MyBugtest);
   BugReport bug = new BugReport()restore(fis); 
  這更簡單!是不是Java的功能越來越強大了?
  現在我們修改第二個例子的第使對象被寫入一個字節數組而不是一個文件:
  
   import javaio*
  
  
   BugReport bug = new BugReport( Crashes when spell checker invoked );
   字 節ArrayOutputStream os = new 字 節ArrayOutputStream();
   bugsave(os); 
  好了我們已經構造了一個對象並且學會把它序列化後放入一個字節OutputStream然 後我們將把這個字節OutputStream轉化為一個Base編碼的字符串
  Base編碼
  目前的Internet Email標准簡單郵件傳遞協議(SMTP)在RFC中宣布對於我們來說 RFC對郵件的內容規定了兩條重要但不難實現的限制
  郵件的內容必須全部為比特的美國ASCII碼
  每一行的長度不能超過的字符
  因此為了通過SMTP用Email進行傳送內存的序列化對象必須轉化為和以上相容的格式
  RFC提供了一個可行的方案它定義了郵件的內容部分使之能包涵多種形式的數 據這種標准就是目前眾所周知的MIME
  按照RFC編碼過程為:輸入是個比特輸出是個字節個比特輸入組從左至右 由比特的輸入組形成個比特被看成個連續的比特組而每個比特輸入組被翻 譯為Base碼表中的一個數字
  這意味著如果我們有下面的個字節的輸入xCxFxFF它將會被轉化為如下 的Base的編碼:xxFxFxF
  
  圖Base編碼實例
  Base編碼似乎有點神秘但實現它的代碼卻非常簡單在下面的程序中我們可以看到 這一點在這個例子中我們創建了一個新類Codecs現在Codecs有兩個方法函數:一 個用來對字符數組編碼一個用來對String類編碼對String類編碼的方法函數簡單地調 用String類的getBytes()函數然後對返回的結果字符數組進行編碼我們將增加從Base解 碼至原先格式的方法函數
  
   public class Codecs {
   private Codecs() {} // do not instantiate this class
  
   public final static String baseEncode(String strInput) {
   if (strInput == null) return null;
   byte byteData[] = new byte[strInputlength()];
   strInputgetBytes( strInputlength() byteData );
   return new String(baseEncode(byteData) );
   }
  
   public final static byte[] baseEncode(byte[] byteData) {
   if (byteData == null) return null;
   int iSrcIdx; // index into source (byteData)
   int iDestIdx; // index into destination (byteDest)
   byte byteDest[] = new byte[((byteDatalength+)/)*];
  
   for
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26869.html
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.