2012-10-14 66 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请求成功返回时弹出窗口显示。但是,客户端可能在报告完成时已注销,因此在用户登录时,可以在“准备报告”部分中再次使用下载链接,这可能是个好主意。