2012-10-14 46 views
1

我有一個Java Servlet,使一些報告。當用戶選擇一個報告時,它會對數據庫進行查詢並將xls報告傳輸到客戶端。全部採用同步方式。問題是,有時我有很多記錄要從數據庫中獲取,我想提供更好的用戶體驗,允許用戶在報告正在處理時做其他事情,並以某種方式彈出過程完成。有沒有一個Java庫或一些技術來避免長時間等待並實現該目標?經過長時間的等待發送文件給客戶端

現在我準備了一段代碼,以異步方式完成報告併發送一封電子郵件給已註冊的客戶端,使用來自下載文件的url,但必須用其他內容替換它,因爲我不能再通過電子郵件進行溝通。

在此先感謝

+0

只需使用多個線程,每個進程都有一個線程。 – OmniOwl

回答

-1

也許你可以在後臺使用java線程?

0

一個多線程的客戶端服務器程序來下載我的圖像文件。 由於有四個文件要下載,客戶端會進行4次連接嘗試。這並不限於4,但FileServer發送的文件將在第四次嘗試後重復。保存對話框和文件保存在不同的線程中完成,以免妨礙文件下載。

這裏是文件服務器...

public class FileServer { 
    private final ExecutorService exec = Executors.newCachedThreadPool(); 

    final String[] fileNames = { 
      "C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 1.jpg", 
      "C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 2.jpg", 
      "C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 3.jpg", 
      "C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 4.jpg" 

    }; 

    public void start() throws IOException { 
     ServerSocket socket = new ServerSocket(7777); 
     System.out.println("Waiting for client message..."); 

     while (!exec.isShutdown()) { 
      try { 
       for (final String fileName : fileNames){ 
        final Socket conn = socket.accept(); 

        exec.execute(new Runnable() { 
         public void run() { 
          sendFile(conn,fileName); 

         } 
        }); 
       } 
      } catch (RejectedExecutionException e) { 
       if (!exec.isShutdown()) 
        log("task submission rejected", e); 
      } 
     } 
    } 

    public void stop() { 
     System.out.println("Shutting down server..."); 
     exec.shutdown(); 
    } 

    private void log(String msg, Exception e) { 
     Logger.getAnonymousLogger().log(Level.WARNING, msg, e); 
    } 

    public void sendFile(Socket conn, String fileName) { 
     File myFile = new File(fileName); 
     if (!myFile.exists()) { 
      log("File does not exist!",null); 
     } 

     // file does exist 
     System.out.println(Thread.currentThread().getName()); 
     System.out.println("AbsolutePath:" + myFile.getAbsolutePath()); 
     System.out.println("length: " + myFile.length()); 

     if (myFile.exists()) { 
      try { 
       ObjectOutputStream oos = new ObjectOutputStream(
       conn.getOutputStream()); 
       oos.writeObject(myFile); 
       oos.close(); 
      } catch (IOException e) { 
       log("IOException Error", e); 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String[] args) throws IOException { 

     FileServer fs = new FileServer(); 
     fs.start(); 
    } 
} 

這裏是FileServerClient ...

public class FileServerClient { 

    private final ExecutorService exec = Executors.newCachedThreadPool(); 
    Frame myFrame = new Frame(); 
    List<File> fileList = new ArrayList<File>(); 

    public void receiveFileFromServer() throws Exception{ 

     Socket sock = null; 
     InputStream socketInputStream = null; 
     String host = "localhost"; 
     int port = 7777; 

     for (int i=0;i<4;i++) { 

      sock = new Socket(host, port); 
      socketInputStream = sock.getInputStream(); 
      System.out.println("Connection successful..."); 

      // recieve the file 
      ObjectInputStream ois = new ObjectInputStream(socketInputStream); 

      // file from server is deserialized 
      final File myfile = (File) ois.readObject(); 
      fileList.add(myfile); 

      // deserialized file properties 
      System.out.println("AbsolutePath: " + myfile.getAbsolutePath()); 
      System.out.println("FileName:" + myfile.getName()); 
      System.out.println("length" + myfile.length()); 
      exec.execute(new Runnable() { 
       public void run() { 

        saveFile(myfile); 

       } 
      }); 

     } 

    } 

    private void saveFile(File myfile) { 
     FileDialog fileDialog = new FileDialog(myFrame, 
       "Choose Destination for "+ myfile.getName(), FileDialog.SAVE); 
     fileDialog.setDirectory(null); 
     fileDialog.setFile("enter file name here"); 
     fileDialog.setVisible(true); 

     String targetFileName = fileDialog.getDirectory() 
       + fileDialog.getFile() + ".jpg"; 

     System.out.println("File will be saved to: " + targetFileName); 

     copyBytes(myfile, targetFileName); 
    } 

    private void copyBytes(File originalFile, String targetFileName) { 

     try { 
      FileInputStream in = new FileInputStream(originalFile); 
      FileOutputStream out = new FileOutputStream(targetFileName); 
      int c; 

      while ((c = in.read()) != -1) { 
       out.write(c); 
      } 
      out.close(); 
      in.close(); 

     } catch (Exception e) { 
      log("IOException Error", e); 
     } 

    } 

    private void log(String msg, Exception e) { 
     Logger.getAnonymousLogger().log(Level.WARNING, msg, e); 
    } 

    public static void main(String[] args) throws Exception { 

     FileServerClient client = new FileServerClient(); 

     client.receiveFileFromServer(); 

    } 

} 
1

繼承人我拿到這個,我不知道一個庫,將完全匹配您的需要,你可能需要一些自定義的開發。

  • 我相信你已經實現了異步服務,完成後發送 出一封電子郵件通知。讓 線程更新某種作業表 - 一個db表 或某個應用程序/會話範圍映射中的條目,而不是發送電子郵件。
  • 有一個servlet/restful ws
  • 在某個網址顯示該工作表。以常規的 間隔輪詢網址。 Ajax輪詢是js庫中的標準功能JQuery, Prototype。
  • 當您收到某個報告完成的回覆時,顯示 某些彈出式窗口,或者可能是您在客戶端上的某個類別的事件 。

我在這裏還沒有考慮認證/授權問題,你也需要照顧。

希望這有助於

0

您可以從客戶端發出異步請求。讓我們假設你的客戶端是一個html頁面。當用戶選擇一個報告並點擊'提交'時,你可以用報告參數(jQuery對此有用)來觸發ajax請求。最好在用戶主頁上保留一段說明「準備好的報告」的部分。然後客戶可以到準備好的報告部分下載報告。如上述註釋中所述,您可能還必須實施彈出窗口,通知用戶所請求的報告已準備就緒。當ajax請求成功返回時彈出窗口顯示。但是,客戶端可能在報告完成時已註銷,因此在用戶登錄時,可以在「準備報告」部分中再次使用下載鏈接,這可能是個好主意。