2011-07-15 15 views
0

我有一個會話bean,它從數據庫中檢索數據並對其進行格式化。在不久的將來,它將需要調用一個實用程序(包裝XML-RPC)來轉發數據,但現在,我需要執行一個命令行腳本,它將一個文件作爲輸入(即'command -f filename') 。我真的不喜歡從會話bean寫入文件的想法(並且JBoss會讓我這麼做嗎?),並且我一直在爲打開CGI腳本打開一個URL,但這看起來有些過分。那麼,將這些數據存入文件最乾淨,最簡單的方法是什麼,以便我可以調用該命令?將數據從無狀態會話bean移動到文件

附加信息:

  • 我們的服務器是JBoss和它不聚集。
  • 數據可能很大,可能包含10,000條XML編碼數據(如果絕對必要,可以將其分成更小的塊)。

TIA, 丙基三甲氧基硅烷

回答

0

這裏有一個比較簡單的辦法讓你的內容到一個文件中。

在你的會話bean,實現一個看起來像一個業務方法:

public Object getContent(String fileName, <Other Args>) { 
    // Get content 
    // write to a byte array 
    byte[] content = ......; 
    return new ByteArrayFile(content, fileName); 
} 

的方法實現應獲得的數據(從DB)和它序列化到一個字節數組,然後加載(沿帶有一個可選的文件名)插入ByteArrayFile的實例並返回。

ByteArrayFile是可序列化的對象,它實現了一個readResolved方法將字節數組轉換爲本地文件(使用提供的名稱或一個臨時文件),並返回給調用者爲java.io 。文件

這裏有一個粗略的實施ByteArrayFile

public class ByteArrayFile implements Serializable { 
    protected final byte[] content; 
    protected final String fileName; 

    /** 
    * Creates a new ByteArrayFile 
    * @param content The file content 
    */ 
    public ByteArrayFile(byte[] content) { 
     this(content, null); 
    } 

    /** 
    * Creates a new ByteArrayFile 
    * @param content The file content 
    * @param fileName The file name to deserialize as 
    */ 
    public ByteArrayFile(byte[] content, String fileName) { 
     super(); 
     this.content = content; 
     this.fileName = fileName; 
    } 

    /** 
    * Returns this object as a resolved file when the object is deserialized. 
    * @return 
    * @throws ObjectStreamException 
    */ 
    protected Object readResolve() throws ObjectStreamException { 
     FileOutputStream fos = null; 
     try { 
      File f = fileName==null ? File.createTempFile(getClass().getSimpleName(), ".file") : new File(fileName); 
      if(!f.canWrite()) { 
       throw new Exception("Unable to write to designated file [" + fileName + "]", new Throwable());    
      } 
      fos = new FileOutputStream(f); 
      fos.write(content); 
      fos.close(); 
      fos = null; 
      return f; 
     } catch (Exception e) { 
      throw new RuntimeException("Failed to readResolve", e); 
     } finally { 
      try { if(fos!=null) fos.close(); } catch (Exception e) {} 
     } 
    } 
} 

這是一個簡化的(即不是一個遠程EJB調用)爲例,說明創建ByteArrayFile,序列化,然後回讀的文件:

public static void main(String[] args) { 
    ByteArrayFile baf = new ByteArrayFile("Hello World".getBytes()); 
    try { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     ObjectOutputStream oos = new ObjectOutputStream(baos); 
     oos.writeObject(baf); 
     oos.flush(); 
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
     ObjectInputStream ois = new ObjectInputStream(bais); 
     File file = (File)ois.readObject(); 
     System.out.println("File:" + file.getAbsolutePath() + " Size:" + file.length()); 
    } catch (Exception e) { 
     e.printStackTrace(System.err); 
    } 
} 

產量爲:

文件:/tmp/ByteArrayFile2790187442947455193.file大小:11

說實話,你的會話bean可以直接絕對寫入文件。嚴格的EJB限制不會被JBoss強制執行,而是用於提供您可能不關心的可移植性保證。但是,上述方法的好處是遠程客戶端可以遠程調用該呼叫,但是可以在本地獲取該文件。

+0

尼古拉斯 - 感謝您的詳盡描述。 – Ilane

+0

這是使用文件調用命令的會話bean - 通過調用另一個使用Runtime.getRuntime()。exec運行所需命令的現有無狀態會話bean(是的,這可能是不允許的,是嗎?功能已經存在。傳統軟件 - 一定要喜歡它!)所以業務方法是「sendContent()」。該文件只有兩個EJB才能知道。由於我們沒有將對象傳遞給遠程客戶端,何時/如何將對象反序列化。是否將第二屆會話bean的方法作爲參數進行調用? – Ilane

相關問題