125

ここで、ファイルは移植可能ではなく、トランザクションに対応しておらず、外部パラメーターを必要とするため、とにかくサーバーにファイルを保存すべきではないことを読みました。ただし、Tomcat(7)のtmpソリューションが必要であり、サーバーマシンを(相対的に)制御できることを考えると、知りたい:

  • ファイルを保存するのに最適な場所は? 私はそれを保存する必要がありますか(ここで/WEB-INF/uploadsはお勧めしません)または下のどこかに保存する必要がありますか(ここを参照)または...?JavaEE 6 チュートリアルは、ユーザー(:wtf:) からパスを取得します。NB : ファイルは決してダウンロード可能であってはなりません。$CATALINA_BASE

  • ここで説明されているように、構成パラメーターを設定する必要がありますか? いくつかのコードをいただければ幸いです(相対パスを指定したいので、少なくともTomcatで移植可能です)-Part.write()有望に見えますが、明らかに絶対パスが必要です

  • このアプローチとデータベース/JCRリポジトリの欠点の説明に興味があります

残念ながら、 @BalusC によるFileServlet はファイルのダウンロードに集中していますが、ファイルのアップロードに関する彼の回答は、ファイルの保存場所に関する部分をスキップしています。

DB または JCR 実装 ( jackrabbitなど) を使用するように簡単に変換できるソリューションが望ましいでしょう。

4

2 に答える 2

170

アップロードされた画像は、ページを更新した後にのみ利用可能への回答に記載されている理由により、IDE のプロジェクト フォルダー (別名サーバーのデプロイ フォルダー)以外のアクセス可能な場所に保存します。

  1. IDE のプロジェクト フォルダーの変更は、サーバーの作業フォルダーにすぐには反映されません。IDE には、サーバーの作業フォルダーが最後の更新と同期されるように処理する一種のバックグラウンド ジョブがあります (これは IDE 用語で「発行」と呼ばれます)。これが、あなたが見ている問題の主な原因です。

  2. 実際のコードでは、アップロードされたファイルを webapp の deploy フォルダーに保存してもまったく機能しない場合があります。一部のサーバーは (デフォルトまたは構成により) 展開された WAR ファイルをローカル ディスク ファイル システムに展開せず、メモリ内に完全に展開します。基本的にデプロイした WAR ファイルを編集して再デプロイしないと、メモリ内に新しいファイルを作成することはできません。

  3. サーバーが展開された WAR ファイルをローカル ディスク ファイル システムに展開した場合でも、新しく作成されたすべてのファイルは、再展開または単純な再起動で失われます。これは、それらの新しいファイルが元の WAR ファイルの一部ではないためです。

methodを使用しない限り、ローカルディスクファイルシステムの正確な場所に保存されるかどうかはgetRealPath()、私や他の誰かにとって本当に重要ではありませ。その方法を使用することは、いずれにせよ驚くべきことです。

ストレージの場所へのパスは、さまざまな方法で定義できます。あなたはそれをすべて自分でしなければなりません。サーバーが自動的にすべてを行うと何らかの形で期待していたため、おそらくこれが混乱の原因です。@MultipartConfig(location)は最終的なアップロード先を指定していませが、ケースファイルのサイズの一時的な保存場所がメモリストレージのしきい値を超えていることに注意してください。

したがって、最終的な保存場所へのパスは、次のいずれかの方法で定義できます。

  • ハードコード:

      File uploads = new File("/path/to/uploads");
    
  • 経由の環境変数SET UPLOAD_LOCATION=/path/to/uploads

      File uploads = new File(System.getenv("UPLOAD_LOCATION"));
    
  • 経由のサーバー起動時の VM 引数-Dupload.location="/path/to/uploads":

      File uploads = new File(System.getProperty("upload.location"));
    
  • *.propertiesファイルエントリとしてupload.location=/path/to/uploads

      File uploads = new File(properties.getProperty("upload.location"));
    
  • web.xml <context-param>名前upload.locationと値/path/to/uploads:

      File uploads = new File(getServletContext().getInitParameter("upload.location"));
    
  • 存在する場合は、JBoss AS/WildFlyなどのサーバー提供の場所を使用します。

      File uploads = new File(System.getProperty("jboss.server.data.dir"), "uploads");
    

どちらの方法でも、次のようにファイルを簡単に参照して保存できます。

File file = new File(uploads, "somefilename.ext");

try (InputStream input = part.getInputStream()) {
    Files.copy(input, file.toPath());
}

または、一意のファイル名を自動生成して、ユーザーが偶然に同じ名前で既存のファイルを上書きしないようにする場合は、次のようにします。

File file = File.createTempFile("somefilename-", ".ext", uploads);

try (InputStream input = part.getInputStream()) {
    Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}

JSP/サーブレットで取得する方法は、JSP/サーブレットを使用してサーバーにファイルをアップロードする方法partで回答されていますか? また、JSF で取得する方法は、 How to upload file using JSF 2.2 <h:inputFile>?で回答されています。保存されたファイルはどこにありますか?part

注: は、 で定義された一時的な保存場所からの相対パスを解釈するため、使用しないでください。また、 /の代わりに/を誤って使用して読み取り/書き込み中にバイトを文字に変換することにより、PDF ファイルや画像ファイルなどのバイナリ ファイルを破損していないことを絶対に確認してください。Part#write()@MultipartConfig(location)ReaderWriterInputStreamOutputStream

以下も参照してください。

于 2013-09-06T18:58:46.917 に答える