NetBeans Visual Web JSF アプリケーションでのファイルのアップロード
このチュートリアルでは、NetBeans IDE 6.0 と 6.1 を使用して、画像ファイル (JPEG、PJPEG、GIF、PNG、または X-PNG) をアップロードして表示する方法について説明します。また、テキストファイルのアップロード方法に関する簡単なチュートリアルもあります。
目次
このチュートリアルに従うには、次のソフトウェアとリソースが必要です。
| NetBeans IDE |
Web および Java EE の version 6.1 または 6.0 |
| Java Development Kit (JDK) |
version 6 または
version 5 |
JavaServer Faces コンポーネント /
Java EE プラットフォーム |
1.2 と Java EE 5* または
1.1 と J2EE 1.4 |
| GlassFish アプリケーションサーバー |
V2 |
| Travel データベース |
任意 |
* NetBeans IDE の Java EE 5 機能を活用するためには、GlassFish アプリケーションサーバー V2 UR2 などの、Java EE 5 仕様に完全に準拠したアプリケーションサーバーを使用してください。別のサーバーを使用している場合は、「リリースノート」と「FAQ」で既知の問題やその回避策を確認してください。サポートされているサーバーと Java EE プラットフォームについては、「リリースノート」を参照してください。
NetBeans IDE 6.1 を使用している方へ
NetBeans 6.1 でプロジェクトを作成すると新しいオプションが含まれますが、これらのオプションはデフォルトのままでかまいません。たとえば、「ライブラリの格納用に専用フォルダを使用」チェックボックスは選択しないままにします。
NetBeans IDE 6.1 には、要求時バインド機能があります。コンポーネントに Java コーディングが必要な場合は、Visual Web JSF アプリケーション内のコンポーネントにバインド属性を手動で追加する必要があります。バインド属性を追加するには、各コンポーネントを右クリックし、「バインド属性を追加」を選択します。詳細は、「On-demand Binding Attribute Wiki」を参照してください。
ファイルアップロードコンポーネントについて
ファイルアップロードコンポーネントによって、Web アプリケーションのユーザーはシステム内でファイルを探し、そのファイルをサーバーにアップロードできます。このコンポーネントは、テキストファイル、イメージファイル、およびその他のデータを収集する場合に便利です。アップロードされるファイルの内容は、ファイル名、サイズ、および MIME タイプ (text/plain や image/jpeg など) を含む、いくつかのファイル情報とともに格納されます。
サーバーは、4096 バイトを超えないかぎり、アップロードされたファイルをメモリーに保持します。4096 バイトを超える場合は、一時ファイルにファイル内容を保持します。このしきい値を変更するには、Web アプリケーションの web.xml ファイルで、UploadFilter フィルタエントリの sizeThreshold パラメータを変更します。web.xml ファイルの変更については、このチュートリアルの最後の節「その他の可能な操作: 最大ファイルアップロードサイズの変更」を参照してください。
アップロードしたファイルを保存する必要がある場合は、次の 3 とおりの方法があります。
- このチュートリアルに示すように、ファイルを任意の場所に書き込みます。
- 管理対象 Bean に「
UploadedFile」プロパティーを作成し、ページを終了する前にコンポーネントの値に設定します (ボタンのアクションメソッドと同様)。
- ファイルをデータベースに保存します。
デフォルトでは、ファイルアップロードコンポーネントは最大 1M バイトのファイルに対処できます。最大ファイルサイズを変更するには、アプリケーションの web.xml ファイル内の UploadFilter フィルタエントリの maxSize パラメータを変更します。詳細は、このチュートリアルの最後の節「その他の可能な操作: 最大ファイルアップロードサイズの変更」を参照してください。
ファイルアップロードコンポーネントを含むページの作成
最初に、ユーザーがアップロードするファイルを選択できるフォームを構築します。
注: NetBeans IDE 6.1 には要求時バインド機能があります。コンポーネントに Java コーディングが必要な場合は、Visual Web JSF アプリケーション内のコンポーネントにバインド属性を手動で追加する必要があります。バインド属性を追加するには、各コンポーネントを右クリックし、「バインド属性を追加」を選択します。詳細は、「On-demand Binding Attribute Wiki」を参照してください。
-
新しい Web アプリケーションプロジェクトを「FileUploadExample」という名前で作成し、Visual Web JavaServer Faces フレームワークを有効にします。
次の図に、このあとの手順で作成するページを示します。
- パレットの「基本」セクションから、「ラベル」コンポーネントをページにドロップし、「
Choose a File to Upload:」と入力して Enter キーを押します。
- 「ファイルアップロード」コンポーネントをページにドラッグし、「ラベル」コンポーネントの下にドロップします。
- 「ボタン」コンポーネントをページにドラッグし、「
Upload File」と入力して、Enter キーを押します。「プロパティー」ウィンドウで、ボタンの「id」プロパティーを「uploadFileButton」に設定します。
- 「ラベル」コンポーネントをページにドラッグし、テキストを「
File Name:」に設定します。
- ラベルの右に「静的テキスト」コンポーネントを配置します。「プロパティー」ウィンドウで、静的テキストの「
id」プロパティーを「fileNameStaticText」に設定します。
- ラベルをもう 1 つページにドラッグします。ラベルのテキストを「
File Type:」に設定します。
- 新しいラベルの右に「静的テキスト」コンポーネントを配置します。静的テキストの「
id」を「fileTypeStaticText」に設定します。
- 別のラベルと静的テキストの組み合わせをページにドラッグします。ラベルのテキストを「
File Size:」に設定し、静的テキストの「id」を「fileSizeStaticText」に設定します。
- 「静的テキスト」コンポーネントの下に「画像」コンポーネントを配置します。
- 「画像」コンポーネントの下に「メッセージグループ」コンポーネントを配置します。
画像のアップロードを処理するコードの追加
基本的なファイルアップロードフォームが完成したので、ファイルのアップロードを処理するコードを追加する必要があります。
注: NetBeans IDE 6.1 には要求時バインド機能があります。コンポーネントに Java コーディングが必要な場合は、Visual Web JSF アプリケーション内のコンポーネントにバインド属性を手動で追加する必要があります。バインド属性を追加するには、各コンポーネントを右クリックし、「バインド属性を追加」を選択します。詳細は、「On-demand Binding Attribute Wiki」を参照してください。
「Upload File」ボタンをダブルクリックして Java エディタを開き、ボタンのイベントハンドラ uploadFileButton_action をページ Bean に追加します。
このメソッドにコードを追加する前に、画像ファイルを保存する変数を定義し、init() メソッドと prerender() メソッドにコードを追加します。
init() メソッドまで上にスクロールし、次の 2 つの変数をメソッドの前に追加します。
| コード例 1: 変数 |
private String realImageFilePath;
private static final String IMAGE_URL = "/resources/image-file"; |
変数 realImageFilePath は、サーバー上での画像ファイルの実際のパスとファイル名です。IMAGE_URL 変数は、実行中の Web アプリケーション内での画像ファイルの論理パスです。
-
次のボールドの行 (ボールドで表示された部分) を init メソッドの末尾に追加します。ただし、コードには「クラスが見つかりません」エラーが含まれます。手順 6 でインポート文を追加し、これらのエラーを修正します。コードを挿入したら、Ctrl-Shift-F キーを押してコードを再整形できます。
| コード例 2: init メソッド |
public void init() {
super.init();
// Perform application initialization that must complete
// *before* managed components are initialized
// TODO - add your own initialiation code here
// Managed Component Initialization
// Perform application initialization that must complete
// *after* managed components are initialized
// TODO - add your own initialization code here
ServletContext theApplicationsServletContext =
(ServletContext) this.getExternalContext().getContext();
this.realImageFilePath = theApplicationsServletContext.getRealPath(IMAGE_URL);
}
|
このコードでは、ファイルをサーバー上の適切なディレクトリに書き込めるように、IMAGE_URL を実際の画像ファイルのパスに変換しています。
-
prerender メソッドまでスクロールし、次のコードを追加します。
| コード例 3: prerender メソッド |
public void prerender() {
String uploadedFileName = (String)
this.fileNameStaticText.getValue();
if ( uploadedFileName != null ) {
image1.setUrl(IMAGE_URL);
}
}
|
表示する画像ファイルがある場合は、このコードでファイルが画像コンポーネントにバインドされます。
uploadFileButton_action() メソッドに次のコードを追加します。
| コード例 4: 画像ファイルをアップロードするコード |
public String uploadFileButton_action() {
UploadedFile uploadedFile = fileUpload1.getUploadedFile();
if( uploadedFile == null ) return null;
String uploadedFileName = uploadedFile.getOriginalName();
// 完全パス名を返すブラウザと返さないブラウザがある
// ファイル名だけを取得するように注意すること
// 最初にスラッシュを試行
int index = uploadedFileName.lastIndexOf('/');
String justFileName;
if ( index >= 0) {
justFileName = uploadedFileName.substring( index + 1 );
} else {
// バックスラッシュを試行
index = uploadedFileName.lastIndexOf('\\');
if (index >= 0) {
justFileName = uploadedFileName.substring( index + 1 );
} else {
// スラッシュもバックスラッシュもなし
justFileName = uploadedFileName;
}
}
this.fileNameStaticText.setValue(justFileName);
Long uploadedFileSize = new Long(uploadedFile.getSize());
this.fileSizeStaticText.setValue(uploadedFileSize);
String uploadedFileType = uploadedFile.getContentType();
this.fileTypeStaticText.setValue(uploadedFileType);
if ( uploadedFileType.equals("image/jpeg")
|| uploadedFileType.equals("image/pjpeg")
|| uploadedFileType.equals("image/gif")
|| uploadedFileType.equals("image/png")
|| uploadedFileType.equals("image/x-png")) {
try {
File file = new File(this.realImageFilePath);
uploadedFile.write(file);
} catch (Exception ex) {
error("Cannot upload file: " + justFileName);
}
} else {
error("You must upload a JPEG, PJPEG, GIF, PNG, or X-PNG file.");
new File(this.realImageFilePath).delete();
}
return null;
} |
プログラムでは、ファイルごとに UploadedFile オブジェクトからファイルの名前、サイズ、種類を抽出し、静的テキストコンポーネントにバインドしています。このプログラムは、すべてのアップロードで主要な決定を行なっています。ファイルが JPEG、PJPEG、GIF、PNG、または X-PNG ファイルの場合、アップロードされたファイルを realImageFilePath 変数に保存します。ファイルが有効な画像ファイルではないか、ファイルのアップロード時にその他の問題が発生した場合は、画像をサーバーから削除し、エラーメッセージを表示します。
-
Java エディタを右クリックし、「インポートを修正」を選択します。「インポートを修正」ダイアログで、java.io.File が「ファイル」ドロップダウンリストに表示されることを確認し、「了解」をクリックします。
この操作でコード内のエラーが修正されます。
アプリケーションのテスト
- アプリケーションを実行します。
-
「参照」をクリックしてローカルドライブ内を移動し、アップロードする画像ファイルを選択します。「Upload File」ボタンをクリックします。
次の図に、JPEG ファイルをアップロードしたアプリケーションを示します。画像は <プロジェクトディレクトリ>\FileUploadExample\build\web\resources に保存されます。

-
ファイルアップロードコンポーネントにテキストファイルを入力し、「Upload File」ボタンをクリックします。エラーメッセージが表示されることを確認します。
注: ファイルアップロードコンポーネントの描画は Web ブラウザによって異なります。このため、ユーザーが使用すると予想されるすべての Web ブラウザでこのコンポーネントをテストしてください。
その他の可能な操作 #1: テキストファイルのアップロード
この節は、テキストファイルのアップロード方法を示す簡単なチュートリアルです。この例では、テキスト領域コンポーネントにファイルの内容を表示し、メッセージグループコンポーネントにファイルの名前とサイズを表示します。この例ではファイルの内容は保存しません。ファイルの内容を保存するには、前の例のようにファイルをディスクに保存するコードを追加する必要があります。
注: NetBeans IDE 6.1 には要求時バインド機能があります。コンポーネントに Java コーディングが必要な場合は、Visual Web JSF アプリケーション内のコンポーネントにバインド属性を手動で追加する必要があります。バインド属性を追加するには、各コンポーネントを右クリックし、「バインド属性を追加」を選択します。詳細は、「On-demand Binding Attribute Wiki」を参照してください。
- Visual Web JavaServer Faces フレームワークを有効にする新しい Web アプリケーションプロジェクトを作成します。
- 「ファイルアップロード」コンポーネントをページにドラッグします。
- 「ボタン」コンポーネント、「テキスト領域」コンポーネント、「メッセージグループ」コンポーネントを追加します。
注: NetBeans IDE 6.1 には要求時バインド機能があります。NetBeans IDE 6.1 を使用している場合は、Java コード内でスクリプトを記述するコンポーネントにバインド属性を手動で追加する必要があります。バインド属性を追加するには、各コンポーネントを右クリックし、「バインド属性を追加」を選択します。詳細は、「On-demand Binding Attribute Wiki」を参照してください。
-
「ボタン」コンポーネントをダブルクリックし、次のアクションコードを button1_action() メソッドに追加します。
| コード例 5: テキストファイルをアップロードするテキスト |
public String button1_action() {
UploadedFile uploadedFile = (UploadedFile)
fileUpload1.getUploadedFile();
if( uploadedFile == null ) return null;
info("Uploaded file originally named '" +
uploadedFile.getOriginalName() +
"' of size '" + uploadedFile.getSize() + "'");
textArea1.setText(uploadedFile.getAsString());
return null;
} |
| |
- Ctrl-Shift-I キーを押してインポートを修正し、
UploadedFile のインポート文を自動的に追加します。
-
アプリケーションを実行します。テキストファイルをアップロードしたページのサンプルを次の図に示します。
その他の可能な操作 #2: 最大ファイルアップロードサイズの変更
1M バイトよりも大きいファイル (大きな画像ファイル、ZIP、JAR、実行可能ファイルなど) のアップロードを有効にするには、アプリケーションの web.xml ファイルで UploadFilter フィルタの maxSize パラメータを変更する必要があります。
- 「ファイル」ウィンドウで「<プロジェクト名>」>「web」>「WEB-F」の順に展開します。
- 「web-xml」ノードを右クリックし、「編集」を選択します。
- XML エディタで「フィルタ」ボタンをクリックします。
UploadFilter の maxSize パラメータを選択し、「編集」ボタンをクリックします。
-
ダイアログでパラメータ値を目的の値に設定し、「了解」をクリックします。
注: セキュリティー上の理由により、maxSize パラメータは負の値に設定しないでください。負の値に設定すると、ファイルサイズの制限がなくなります。
- 「ファイル」>「保存」を選択して、変更を保存します。
注: アプリケーションのユーザーが maxSize パラメータの値よりも大きいファイルをアップロードしようとすると、次の例外がスローされ、妥当性検査エラーとしてキャッチされます。
org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException
ユーザーには次の概要メッセージが表示されます。
ファイルがアップロードされていません。
詳細メッセージは次のようになります。
ファイルがアップロードされていません。指定したファイルは許容サイズ (1000000M バイト) を超えています
ここで 1000000M バイトは maxSize の値です。
その他の可能な操作 #3: アップロードしたファイルのほかの場所への保存
このチュートリアルでは、Web アプリケーションの /resources フォルダにファイルをアップロードする方法を示しています。アップロードしたファイルをほかの場所に保存するにはどうしたらいいのでしょうか。次に、例を示します。
Web アプリケーション内の別のフォルダ
画像は Web アプリケーション内の任意のディレクトリ (Web アプリケーションの web ディレクトリ内の任意のディレクトリ) に保存できます。たとえば、web の下に upload/images サブフォルダを作成し、次のコードを使用してそこに画像を保存できます。
| コード例 6: 別のフォルダにファイルをアップロードするコード |
String realPath = theApplicationsServletContext.getRealPath("/upload/images");
File file = new File(realPath + File.separatorChar + justFileName);
|
アップロードしたファイルを Web アプリケーション内に保存すると、誰でも http://localhost:29080/MyWebApplication/faces/upload/images/myPicture.gif のような URL でファイルにアクセスできるので、注意が必要です。
サーバー上の既知のディレクトリ
サーバー上の別の場所に画像を保存するには、次のようなコードを使用できます。
| コード例 7: サーバー上の既知のディレクトリにファイルをアップロードするコード |
File file = new File("C:/upload/images" + File.separatorChar + justFileName);
uploadedFile.write(file);
|
アプリケーションを複数の異なるサーバーに配備する場合は、次のようなコードを使用して、アップロードディレクトリが存在することを確認できます。
| コード例 8: 異なるサーバーにファイルをアップロードするコード |
File dir = new File("C:/upload/images");
if (! dir.exists()) dir.mkdirs();
File file = new File(dir.getCanonicalPath() + File.separatorChar + justFileName);
uploadedFile.write(file);
|
File クラスについては、http://java.sun.com/j2se/1.3/docs/api/java/io/File.html を参照してください。
現時点では不明なディレクトリ
ディレクトリパスを配備記述子で指定して、場所を動的に変更する方法もあります。
- 「ファイル」ウィンドウで「web」ノードを展開し、「WEB-INF」を展開します。web.xml をダブルクリックして開きます。
- 「一般」ボタンをクリックし、「コンテキストパラメータ」を展開して、「追加」ボタンをクリックします。
-
次の値を設定し、「了解」をクリックします。
パラメータ名: uploadDirectory (任意の名前)
パラメータ値: C:/upload/images (任意のパス)
web.xml ファイルを閉じて保存します。
-
次のコードを使用します。
| コード例 9: ファイルを現時点では不明なディレクトリにアップロードするコード |
String uploadDirectory = getExternalContext().getInitParameter
("uploadDirectory");
File file = new File(uploadDirectory + File.separatorChar + justFileName);
uploadedFile.write(file);
|
既知の問題点
- Internet Explorer 7 でファイルアップロードのチュートリアルを実行した場合、画像の最初の読み込みは正常に行われます。画像の 2 回目の読み込みでは、ファイル名、ファイルの種類、ファイルサイズは更新されますが、画像は更新されません。ブラウザを再読み込みすると画像が正しく表示されます。
- 画像のファイル名には ISO-8859-1 の文字が含まれる必要があります。
関連項目
更新日: 2008 年 4 月 15 日