SpringMVC がファイルをアップロードおよびダウンロードすると、war_exploded デプロイメントによりダウンロードされたファイルが削除されます

この記事はずっと書きたかったのですが、この問題に遭遇して解決した直後に記録しなかったため、その後いくつかの問題が発生してプロジェクトが消滅することになったため、しばらく保留していました。その間、今日は移動できませんでした。この問題を思い出しました。プロジェクトが失われ、もうプロジェクトを再構築したくないので、それを共有します。言葉でしか説明できません。できる限り言葉で伝えますが、かなり前のことなので説明に多少のズレがあるかもしれませんが、見てください。

問題の説明:

SpringMVC のファイルのアップロードとダウンロードを練習する場合、チュートリアル (Qianfeng SSM チュートリアル) に従ってプロジェクトを完了しましたが、ダウンロード時に問題が発生しました: ビデオの先生は正常にダウンロードでき、私のプロジェクトは正常に実行されました。ダウンロードしたファイル(練習用画像)がフォルダ内に見つかりません。デバッグプロセス中に、単一のイメージがダウンロードされたときにプロジェクトが閉じられていないことがわかりました。プロジェクトのターゲットディレクトリにはダウンロードされたファイルがあり、ダウンロードしたイメージは自分で定義したフォルダーにも表示されますが、プロジェクトの終わり、定義されたファイル フォルダー下の画像が消え、ターゲット ディレクトリ内のファイルはまだ存在しますが、プロジェクトが再起動され、ターゲット ディレクトリが更新され、ファイルが消えます。複数のファイルをダウンロードすると、フォルダ配下に最初にダウンロードしたファイルは後でダウンロードされます ファイルは上書きされますが、対象ディレクトリは上書きされません プロジェクトを閉じると、フォルダ内のファイルは消えます。

問題の調査:

この問題に遭遇したとき、私は頭が痛くなりました。エラー報告がなければ、準正常な問題の原因を見つけるのは本当に困難でした。まず、私のコードと先生のコードが一致しているかどうかを慎重に比較したところ、まったく同じであることがわかりました。 ; それから私はインターネット上で自分の問題を説明するために最善を尽くしました インターネット上で答えを探しています、「SpringMVCファイルをダウンロードできない」「SpringMVCファイルをダウンロードすると終了プロジェクトが消える」「SpringMVCファイルを複数のファイルをダウンロードすると上書きされる」からのキーワード以前にダウンロードしたファイルがあり、プロジェクトの終了後にファイルが消えます」...私の問題の説明でさらに詳細を取得した後、答えを見つけました。

理由:

ブロガーの答えはおそらく次のようなものです: 「WAR Exploded デプロイメント モードでは、プロジェクトが終了すると、Web サーバーは Web アプリケーションのリソースを作業ディレクトリから削除します。したがって、ダウンロードされたファイルもすべて削除されます。」なぜ取り上げられるのか、彼はそれについて話していないようだったのを覚えています。

解決:

最も簡単な方法は、デプロイメント方法を「war_exploded」から「war」に直接変更することです。修正方法については、Tomcat の編集をクリック -> デプロイメントをクリック -> 以下のファイルの後ろにある「_exploded」を削除します - > 「適用」をクリック -> 「OK」をクリックします。

要約:

問題の概要:

war_exploded デプロイメントを使用して SpringMVC でファイルをダウンロードすると、次の問題が発生する可能性があります。

  1. フォルダーの下に毎回ダウンロードされるファイルは、以前にダウンロードされたファイルを上書きしますが、プロジェクトのターゲット ディレクトリには上書きされません。

  2. ダウンロードしたファイルはプロジェクトを閉じると消えます。

解決:

デプロイメント方法を「war_exploded」から「war」に直接変更します。Tomcat をクリックして構成を編集 -> デプロイメントをクリック -> 以下のファイルの後ろにある「_exploded」を削除 -> 「適用」をクリック -> 「OK」をクリックします。

徹底的な調査:

その後、war と war_exploded デプロイメントの違いを調べましたので、ここで共有します。

war と war_exploded デプロイメントの違い:

WAR (Web Application Archive) は、Java Web アプリケーションのパッケージ化方法であり、アプリケーションのすべてのリソース (HTML、JSP、Java クラス、構成ファイルなどを含む) を 1 つのファイルにパッケージ化できます。このファイルは、Java アプリケーション サーバー (Tomcat、Jetty、WebLogic など) にデプロイできます。WAR ファイルがアプリケーション サーバーにデプロイされると、サーバーは WAR ファイルを解凍し、その作業ディレクトリにデプロイします。このプロセス中に、Web ページ、Java クラス、リソース ファイルなど、アプリケーション内のさまざまなコンポーネントにアクセスできます。

WAR 展開 (または独立デプロイメントまたは解凍デプロイメント) とは、Web アプリケーションのすべてのリソースをサーバー上のディレクトリに直接デプロイすることを指します。このディレクトリは、Web アプリケーションのコンテキスト ディレクトリ (コンテキスト ディレクトリ) と呼ばれることがよくあります。WAR ファイルとは異なり、このデプロイメント方法では、ファイルを解凍したり、アプリケーションを単一のファイルにパッケージ化したりする必要はありません。アプリケーションは、追加の構成を行わずにサーバー上で直接実行できます。

一般に、WAR ファイルは Java Web アプリケーションのライフサイクルにおいて便利なツールであり、トランスポート、配布、およびデプロイメントを容易にします。これに相当するのが WAR Exploded です。これは、開発者がアプリケーション リソースをより柔軟に検査および変更できるため、Web アプリケーションをローカルで開発およびテストする場合 (IDE 経由で実行する場合など) に便利です。

上記の問題の理由:

これら 2 つの方法の説明に従って、問題の原因を知ることができます。

WAR Exploded デプロイメント方法では、通常、Web アプリケーションのリソースは、WAR デプロイメント方法のように別のファイルにパッケージ化されるのではなく、Web サーバーの特定のディレクトリに直接デプロイされます。

Web アプリケーションの保存場所が適切に構成されていない場合、以前にダウンロードしたファイルが上書きされる可能性があります。これは、各リクエストが同じリソースにアクセスする可能性があり、保存場所が間違っているため、新しくダウンロードされたファイルが以前にダウンロードしたファイルを上書きする可能性があるためです。

さらに、WAR 展開モードでは、プロジェクトが終了すると、Web サーバーは Web アプリケーションのリソースを作業ディレクトリから削除します。その結果、ダウンロードされたすべてのファイルも削除され、ファイルが消える問題が発生する可能性があります。

導入方法を変更しないソリューション:

デプロイメント方法を変更できない場合、この問題も解決できます (答えは chatGPT から得られますが、試行はありません)。

        1. 設定ファイルのアップロード ディレクトリ。

これを回避するには、アプリケーションの構成ファイル (Web.xml など) で名前を付けたコンテキスト パラメーターを定義しupload.location、その値をファイルがアップロードされたディレクトリに設定します。

たとえば、Spring MVC では、次のコードを使用してコンテキスト パラメーターを取得し、ファイルの保存場所を指定できます。

String uploadDir = servletContext.getInitParameter("upload.location");
Path fileStorageLocation = Paths.get(uploadDir).toAbsolutePath().normalize();
Path filePath = fileStorageLocation.resolve(file.getOriginalFilename());

実際のアプリケーションでは、要件に応じてさまざまなアップロード ファイルの場所を選択できます。

        2. 設定ファイルのダウンロード ディレクトリ。

ダウンロードしたファイルが消えないようにするには、ダウンロードしたファイルを Web アプリケーションの外部の場所 (ディスク上の別のパスなど) に保存します。ファイルのダウンロードを実装する場合、最初にファイルを指定したディレクトリにコピーし、次に指定したディレクトリからファイルをクライアントに返すことができます。

たとえば、Spring MVC では、次のコードを使用して、指定されたディレクトリからファイルを読み取り、それをクライアントに返すことができます。

String downloadDir = servletContext.getInitParameter("download.location");
Path fileStorageLocation = Paths.get(downloadDir).toAbsolutePath().normalize();
Path filePath = fileStorageLocation.resolve(fileName);
Resource resource = new UrlResource(filePath.toUri());
return ResponseEntity.ok()
        .contentType(MediaType.parseMediaType(contentType))
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
        .body(resource);

実際のアプリケーションでは、さまざまなダウンロード ファイルの場所やその他の関連構成を選択できます。

おすすめ

転載: blog.csdn.net/m0_56680022/article/details/130139917