Java EE Webアプリケーションを介してサーバー(Webコンテナ)にファイルを保存する方法は?
-
27-09-2019 - |
質問
Java EE Webアプリケーションを開発しました。このアプリケーションを使用すると、ユーザーはブラウザの助けを借りてファイルをアップロードできます。ユーザーがファイルをアップロードすると、このアプリケーションは最初にアップロードされたファイルをサーバーに保存し(実行中です)、それを処理します。
現在、次のようにサーバーにファイルを保存しています。
try {
// formFile represents the uploaded file
FormFile formFile = programForm.getTheFile();
String path = getServlet().getServletContext().getRealPath("") + "/"
+ formFile.getFileName();
System.out.println(path);
file = new File(path);
outputStream = new FileOutputStream(file);
outputStream.write(formFile.getFileData());
}
どこ formFile
アップロードされたファイルを表します。
さて、問題は、一部のサーバーでは正常に実行されているが、一部のサーバーでは getServlet().getServletContext().getRealPath("")
戻ってきています null
だから私が得ている最後の道はそうです null/filename
ファイルはサーバーに保存されません。
APIをチェックしたとき ServletContext.getRealPath()
方法、私は次のことを見つけました:
public java.lang.String getRealPath(java.lang.String path)
特定の仮想パスの実際のパスを含む文字列を返します。たとえば、パス
"/index.html"
サーバーのファイルシステムの絶対ファイルパスを返すことは、"http://host/contextPath/index.html"
, 、ContextPathはこのServletContextのコンテキストパスです。返される実際のパスは、適切なパスセパレーターを含むサーブレットコンテナが実行されているコンピューターおよびオペレーティングシステムに適した形式になります。このメソッドは、サーブレットコンテナが仮想パスを何らかの理由で実際のパスに変換できない場合にnullを返します(コンテンツが.warアーカイブから利用可能になったときなど)。
ですから、それらのサーバーにファイルを保存する他の方法もあります。 null
にとって getServlet().getServletContext().getRealPath("")
解決
Java EEコンテナからファイルシステムへの書き込みは、特に書かれたデータを処理する必要がある場合は、実際にはお勧めしません。
- トランザクションではありません
- それは移植性に害を及ぼします(あなたがクラスター化された環境にいる場合はどうなりますか)
- ターゲットの場所の外部パラメーターをセットアップする必要があります
これがオプションである場合、ファイルをデータベースに保存するか、JCRリポジトリを使用します( ジャックラビット).
他のヒント
仕様では、サーブレットコンテナを形成することが保証されている唯一の「本物の」パスは、TEMPディレクトリです。
あなたはそれを介してそれを得ることができます ServletContext.gerAttribute("javax.servlet.context.tempdir")
. 。ただし、これらのファイルはWebコンテキストには表示されません(つまり、これらのファイルを配信するための簡単なURLを公開することはできません)。ファイルは、Webアプリまたはサーバーの再起動に耐えるためにいかなる方法でも保証されません。
単に作業ファイルを短時間保存する場所が必要な場合は、これは正常に機能します。
実際にディレクトリが必要な場合は、構成パラメーター(環境変数、Javaプロパティ)にすることができます(IE java -Dyour.file.here=/tmp/files ...
)、Web.xmlで設定されたコンテキストパラメーター、Webフォームなどを介してデータベースに保存されている構成パラメーターなど)。その後、このディレクトリを設定するのは展開者次第です。
ただし、実際にそのファイルを提供する必要がある場合は、外部ディレクトリをWebアプリ(「代替Doc Roots」として「Glassfish」に「マウント」するためのコンテナ固有のメカニズムが必要です。 Webアプリの外でファイルストアを提供するために、サーブレット/フィルターを作成する必要があります。これ fileservlet 非常に完全であり、ご覧のとおり、自分で作成することは難しくありませんが、それを正しく行うのは些細なことではありません。
編集:
基本的な要点は同じですが、「getRealPath」を使用するのではなく、「getInitParameter」を使用するだけです。
それで:
String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;
そして、あなたの途中にいます。
もう一度編集:
パスの内容については、絶対的なパスを与えます。それ以外の場合は、アプリサーバーがデフォルトのパスをエクセル作成中に設定する場所を知る必要があり、各アプリサーバーは異なるディレクトリを使用する場合があります。たとえば、Glassfishの作業ディレクトリは実行中のドメインの構成ディレクトリであると思います。特に明白な選択ではありません。
したがって、絶対的なパスを使用してください。そうすれば、ファイルがどこに行くのかがわかり、必要に応じてそのディレクトリのOSレベルでアクセス権限を制御できます。