1

私はいくつかのレポートを作成する Java サーブレットを持っています。ユーザーがレポートを選択すると、データベースでクエリが作成され、xls レポートがクライアントにストリーミングされます。すべて同期的に。問題は、データベースからフェッチするレコードが大量にある場合があり、ユーザーエクスペリエンスを向上させたいことです。レポートの処理中にユーザーが他のことを実行できるようにし、何らかの方法でリンクプロセスが終了しました。長い待ち時間を避けてその目標を達成するためのJavaライブラリまたはいくつかのテクニックはありますか?

現在、非同期でレポートを完成させ、ファイルをダウンロードする URL を含むメールを登録済みのクライアントに送信するコードを用意しましたが、もうできないため、別のものに置き換える必要があります。電子メールで通信します。

前もって感謝します

4

3 に答える 3

1

これについての私の見解です。あなたのニーズに完全に一致する単一のライブラリを知りません。おそらくここでカスタム開発が必要になるでしょう。

  • 完了時に通知用のメールを送信する非同期サービスを実装したと思います。電子メールを送信する代わりに、そのスレッドに、ある種のジョブテーブル(dbテーブルのエントリまたはアプリケーション/セッションスコープのマップ)を更新させます。
  • サーブレット/RESTfulWSを使用する
  • そのジョブテーブルをいくつかのURLで公開します。定期的にURLをポーリングします。Ajaxポーリングは、jsライブラリJQuery、Prototypeの標準機能です。
  • 一部のレポートが完了したという応答を受け取ったら、ポップアップを表示するか、クライアント側でFacebookの通知のようなものである可能性があります。

私はここで認証/承認の問題を考慮していません、あなたもそれを世話する必要があります。

お役に立てれば

于 2012-10-14T15:27:14.217 に答える
0

画像ファイルをダウンロードするためのマルチスレッドクライアントサーバープログラム。ダウンロードするファイルが4つあるため、クライアントは4回の接続を試行します。これは4つに制限されていませんが、FileServerによって送信されたファイルは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();

    }

}
于 2012-10-14T13:41:06.290 に答える
0

クライアントから非同期リクエストを行うことができます。クライアントが html ページであると仮定しましょう。ユーザーがレポートを選択して [送信] をクリックすると、レポート パラメータを使用して ajax リクエストを送信できます (これには jquery が役立ちます)。ユーザーのホームページに「準備レポート」のようなセクションを残しておくとよいでしょう。その後、クライアントは準備済みレポート セクションに移動して、レポートをダウンロードできます。上記のコメントで指定されているように、要求されたレポートの準備ができていることをユーザーに通知するポップアップを実装する必要がある場合もあります。ajax リクエストが正常に返されると、ポップアップが表示されます。ただし、レポートが終了するまでにクライアントがログアウトしている可能性があるため、ユーザーがログインしたときに「準備されたレポート」セクションでダウンロード リンクを再度利用できるようにすることをお勧めします。

于 2012-10-14T15:52:29.680 に答える