11

これが私がしていることです。マルチパートファイルをAjax経由でSpringWebアプリにアップロードしたい。サーバーはPOSTリクエストを受信すると、データベースにチケット番号を作成します。次に、実際のファイルのアップロードを処理するスレッドを開始します。次に、サーバーはチケット番号を返します。

CommonsMultipartResolverを使用してリクエストを処理し、resolveLazilyフラグをtrueに設定して、Multipartがすぐに解決されないようにしました。

だからここに私が持っているものの線に沿った何かがあります

@Controller
public class myController{

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    public String upload(MultipartHttpServletRequest request, String fileName){

        String ticket = dao.createUploadTicket(fileName);
        Runnable run = new Runnable(){

            @Override
            public void run(){

                dao.writeUpdate(ticket, "Getting data from request");
                final MultipartFile file = request.getFile("theFile");
                dao.writeUpdate(ticket, "Multipart file processed");
                try {
                   dao.writeUpdate(ticket, "Saving file to disk");
                   file.transferTo(new File("/myDirectory"));
                   dao.writeUpdate(ticket, "File saved to disk");
                }
                catch(Exception e){
                   dao.writeUpdate(ticket, "File upload failed with the exception " + e.toString());
                }
            }
        };
        Thread t = new Thread(run);
        t.start();
        return ticket;
    }
}

したがって、ここでのポイントは、チケット番号を使用して進捗状況の更新を取得できることです。大きなファイルがアップロードされているとしましょう。ファイルのアップロードをPOSTにしたクライアント(この場合はAjaxリクエストなど)は、非同期でそれを実行し、チケット番号を取得できます。クライアントはそのチケット番号を使用して、ファイルのアップロードの段階を決定し、別のページに情報を表示できます。

もう1つの用途は、すべてのチケット番号をサーバーに要求し、サーバーで行われているすべてのファイルアップロードの「ライブ」ビューを表示するHTMLページを作成できることです。

コントローラが戻るとすぐに、SpringがCommonsMultipartResolverでcleanupMultipart()を呼び出すため、これを機能させることができませんでした。resolveLazilyフラグがfalseに設定されているため、cleanupMultipart()が呼び出されると、マルチパートファイルの解決と初期化が開始されます。これにより、「request.getFile( "theFile");」の呼び出し間の競合状態が発生します。runnableおよびcleanupMultipart()呼び出しで、最終的に例外が発生します。

誰かアイデアはありますか?バックエンドの非同期ファイル処理を実行したいので、ここである種のHTTPコントラクトを破っていますか?

4

1 に答える 1

8

HTTP リクエストはすでに独自のスレッドで実行されており、クライアントはいくつかのリクエストを並行して非同期に行うことができます。したがって、新しいスレッドを開始する必要はありません。メインスレッドで、通常どおりファイルを保存/処理するだけです。クライアント側でのみ「非同期ファイルアップロード」を行うだけです。

また、入力を処理した場合にのみ、http 応答を送信する必要があります。つまり、入力ヘッダーを読み取ったり、http 応答を作成したり、ブラウザーからデータを引き続き読み取ったりすることはできません。入力を消費 -> 処理 -> 出力を送信、HTTP 1/1.1 プロトコルがどのように機能するか。

アップロードするために送信するチケット番号が必要な場合は、次のように 2 段階のアップロードを使用して、実際のアップロードの前にチケット番号を作成できます。

  • チケット番号を取得するAjax GETリクエスト
  • ファイルの内容とチケット番号を POST (前のステップで受け取ったもの)
  • + ajax GET チケットの現在のステータスを取得、いつでも、非同期
于 2012-06-13T05:53:24.960 に答える