web-dev-qa-db-ja.com

アップロードされたファイルをJSFに保存する方法

JSFでファイルをアップロードしています。私はトマホークの<t:inputFileUpload>これには、同じ質問が適用されます。 PrimeFaces <p:fileUpload>およびJSF 2.2 <h:inputFile>

以下のバッキングBeanコードがあります。

private UploadedFile uploadedFile; // +getter+setter

public String save() throws IOException {
    String name = uploadedFile.getName();
    System.out.println("File name: " + name);

    String type = uploadedFile.getContentType();
    System.out.println("File type: " + type);

    long size = uploadedFile.getSize();
    System.out.println("File size: " + size);  

    InputStream stream = uploadedFile.getInputStream();
    byte[] buffer = new byte[(int) size];  
    stream.read(buffer, 0, (int) size);  
    stream.close();  
}

ファイル名、タイプ、サイズを取得することはできますが、このファイルを特定のパスに保存することはできません。アップロードされたファイルを保存する適切な方法がわかりません。どうすればこれを達成できますか?

18
V.Rohan

アップロードされたファイルのgetInputStream()メソッドは、ファイルのコンテンツを表します。

_InputStream input = uploadedFile.getInputStream();
_

ファイルにコピーする必要があります。最初に、アップロードしたファイルを保存するローカルディスクファイルシステムにフォルダーを準備する必要があります。たとえば、_/path/to/uploads_(Windowsでは、サーバーが実行されているディスクと同じディスクにあります)。ここで言及した理由により、相対パスまたはgetRealPath()を使用して、展開されたWARフォルダーにファイルを保存しないでください ページの更新後にのみ利用可能なアップロードされた画像

次に、ファイル名を自動生成する必要があります。そうしないと、誰かが後で同じ名前のファイルを偶然アップロードしたときに上書きされてしまいます。 Files#createTempFile() 機能を使用して、自動生成されたファイル名を取得できます。

_Path folder = Paths.get("/path/to/uploads");
String filename = FilenameUtils.getBaseName(uploadedFile.getName()); 
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);
_

アップロードのパスは、必要に応じて、このQ&Aに示されているいくつかの方法のいずれかに基づいてパラメーター化できます。 アップロードされたファイルをサーブレットアプリケーションに保存する推奨方法FilenameUtilsはApache Commons IOの一部です。これは、Tomahawkファイルアップロードコンポーネントの依存関係であるため、クラスパスに既に存在している必要があります。

最後に、アップロードされたファイルをそのファイルにストリーミングします(Java 7)と仮定):

_try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}

System.out.println("Uploaded file successfully saved in " + file);
_

次に、ダウンロードして戻すには、_/path/to/uploads_を新しいwebappコンテキストまたは仮想ホストとして登録し、それらのファイルがすべてURLで利用できるようにするのが最も簡単です。 <h:graphicImage>または<img>タグを使用してwebapps/webcontext/deployフォルダーの外部から画像を読み込む も参照してください。

55
BalusC

PrimeFacesは、p:fileuploadのコンテンツをアップロードするために2つのファイルアップロードデコーダーを使用します

  1. NativeFileUploadDecoder
  2. CommonsFileUploadDecoder

NativeFileUploadDecoderはデフォルトのアップロードデコーダであり、サーブレットコンテナ3.0が必要です。したがって、サーブレットコンテナが3未満の場合、動作しません。また、一部のアプリケーションサーバーは、マルチパートコンテンツの使用を制限しています

何らかの理由でネイティブアップロードデコーダーに問題がある場合は、「CommonsFileUploadDecoder」である他のデコーダーを使用する必要があります

CommonsFileUploadDecoderはApache common libに依存するため、クラスパスにcommons-fileuploadおよびcommons-io jarsを配置する必要があります。バージョンはprimefacesバージョンに依存しますが、それぞれ1.3および2.2が機能します。

commonsFileUploadDecoderを使用するには、フィルターを使用する必要があります

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

フィルターのみが機能しないのを待つフィルター内でアップローダーが提供されていないかどうかをチェックし、少なくともJSF 2.2を検出し、デフォルトデコーダー「Native」へのリクエストをバイパスしてからあなたのためにも機能しません

フィルタに共通のデコーダを使用させるには、web.xmlに次のコンテキストパラメータを配置する必要があります

<context-param>
<param-name>primefaces.UPLOADER</param-name>
   <param-value>commons</param-value>
</context-param>
1
HMoussa