Загрузка файлов в визуальных веб-приложениях JSF в среде NetBeans
В этом руководстве описывается использование среды IDE NetBeans 6.0 и 6.1 для загрузки и вывода на экран графических файлов (JPEG, PJPEG, GIF, PNG или X-PNG). Также сюда включено мини-руководство по загрузке текстового файла.
Содержание
Для работы с этим руководством требуется программное обеспечение и ресурсы, перечисленные ниже.
| Среда IDE NetBeans |
Web & Java EE, версия 6.1 или 6.0 |
| Комплект для разработчика на языке Java (JDK) |
версия 6 или
версия 5 |
Элементы JavaServer Faces
Платформа Java EE |
1.2 с Java EE 5* или
1.1 с J2EE 1.4 |
| Сервер приложений GlassFish |
V2 |
| База данных TRAVEL |
Не требуется |
* Для получения преимуществ благодаря функциональности Java EE 5 в среде IDE NetBeans используйте сервер приложений, который является полностью совместимым со спецификацией Java EE 5, например, сервер приложений GlassFish V2 UR2. В случае использования другого сервера см. заметки о выпуске и часто задаваемые вопросы для получения информации об известных проблемах и обходных решениях. Для получения подробной информации о поддерживаемых серверах и платформе Java EE см. заметки о выпуске.
Примечание для пользователей среды IDE NetBeans 6.1:
При создании проекта в NetBeans 6.1 доступны новые параметры, для которых можно оставить значения по умолчанию. Например, флажок "Use Dedicated Folder for Storing Libraries" может быть оставлен неустановленным.
В среде IDE NetBeans 6.1 поддерживается привязка по запросу. В тех местах, где элементы требуют написания кода Java, теперь следует вручную добавить атрибут привязки к элементам в визуальном веб-приложении JSF. Для этого щелкните правой кнопкой мыши каждый элемент и выберите "Add Binding Attribute". Для получения дополнительных сведений см. вики-страницу On-demand Binding Attribute.
Описание элемента для загрузки файла
Элемент для загрузки файла "File Upload" позволяет пользователям веб-приложения найти в системе файл и загрузить его на сервер. Этот элемент удобен для сбора текстовых файлов, графических файлов и других данных. Содержимое загруженного файла сохраняется вместе с некоторой информацией о файле, включая имя, размер файла и тип MIME (например, текстовый/простой или графический/jpeg).
Загруженный файл сохраняется в памяти сервера, если он не превышает 4096 байт, в противном случае содержимое сохраняется во временном файле сервера. Это пороговое значение может быть изменено посредством изменения параметра sizeThreshold для записи фильтра UploadFilter в файле веб-приложения web.xml. Для получения дополнительных сведений об изменении файла web.xml см. последний раздел этого руководства Дополнительное упражнение: Изменение максимального размера загружаемого файла.
В случаях, когда требуется сохранить загруженный файл, существует три возможности:
- Сохраните файл в выбранном местоположении, как показано в этом руководстве.
- Создайте свойство
UploadedFile в управляемом компоненте и установите для него значение элемента до закрытия страницы (как в методе действия кнопки).
- Сохраните файл в базе данных.
По умолчанию элемент "File Upload" может обрабатывать файлы размером до одного мегабайта. Максимальный размер файла может быть изменен путем изменения параметра maxSize для фильтра UploadFilter в файле приложения web.xml, как описано в последнем разделе этого руководства Дополнительное упражнение: Изменение максимального размера загружаемого файла.
Создание страницы, имеющей в своем составе элемент "File Upload"
Сначала необходимо создать форму, позволяющую пользователям выбирать файл для загрузки.
Примечание: В среде IDE NetBeans 6.1 поддерживается привязка по запросу. В тех местах, где элементы требуют написания кода Java, теперь следует вручную добавить атрибут привязки к элементам в визуальном веб-приложении JSF. Для этого щелкните правой кнопкой мыши каждый элемент и выберите "Add Binding Attribute". Для получения дополнительных сведений см. вики-страницу On-demand Binding Attribute.
-
Создайте новый проект веб-приложения, в котором будет использоваться инфраструктура визуальных веб-приложений JavaServer Faces, с именем FileUploadExample.
На следующем рисунке показана страница, создаваемая с помощью нижеприведенной процедуры:
- Из раздела "Basic" окна "Palette" перетащите элемент "Label" на страницу, введите
Choose a File to Upload: и нажмите клавишу Enter.
- Перетащите элемент "File Upload" на страницу и поместите его под элементом "Label".
- Перетащите элемент "Button" на страницу, введите
Upload File и нажмите клавишу Enter. В окне "Properties" установите для свойства элемента "Button" id значение uploadFileButton.
- Перетащите элемент "Label" на страницу и установите для текста значение
File Name:
- Разместите элемент "Static Text" справа от элемента "Label". В окне "Properties" установите для свойства
id элемента "Static Text" значение fileNameStaticText.
- Перетащите на страницу другой элемент "Label". Измените текст элемента "Label" на
File Type:
- Разместите элемент "Static Text" справа от нового элемента "Label". Измените значение элемента "Static Text"
id на fileTypeStaticText.
- Перетащите на страницу еще одну пару элементов "Label" и "Static Text". Задайте для элемента "Label" текст
File Size: и установите для свойства id элемента "Static Text" значение fileSizeStaticText.
- Поместите элемент "Image" под элементами "Static Text".
- Поместите элемент "Message Group" под элементом "Image".
Добавление кода для обработки загрузки изображения
Теперь при наличии базовой формы загрузки файла следует добавить код для обработки загрузки файла.
Примечание: В среде IDE NetBeans 6.1 поддерживается привязка по запросу. В тех местах, где элементы требуют написания кода Java, теперь следует вручную добавить атрибут привязки к элементам в визуальном веб-приложении JSF. Для этого щелкните правой кнопкой мыши каждый элемент и выберите "Add Binding Attribute". Для получения дополнительных сведений см. вики-страницу On-demand Binding Attribute.
Дважды нажмите кнопку "Upload File" для открытия редактора Java и добавьте к элементу страницы обработчик событий кнопки uploadFileButton_action.
Перед добавлением к этому методу кода необходимо определить переменные для сохранения графического файла и добавить код к методам init() и prerender().
Выполните прокрутку вверх до метода init() и добавьте перед методом две следующие переменные:
| Пример кода 1: переменные |
private String realImageFilePath;
private static final String IMAGE_URL = "/resources/image-file"; |
Переменная realImageFilePath является фактическим путем и именем графического файла на сервере. Переменная IMAGE_URL является логическим путем графического файла в работающем веб-приложении.
-
Добавьте следующие полужирные строки (выделены полужирным шрифтом) в конец метода init, однако обратите внимание на то, что код содержит ошибку "Class Not Found". Для исправления этих ошибок в действии 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);
}
}
|
При наличии графического файла, который требуется вывести на экран, этот код связывает файл с элементом "Image".
Добавьте следующий код к методу 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" имя файла, его размер и тип и связывает их с элементами "Static Text". При каждой загрузке программой принимается основное решение: если файл принадлежит к формату JPEG, PJPEG, GIF, PNG или X-PNG, программа сохраняет загруженный файл в переменной realImageFilePath. Если файл не является действительным графическим файлом, а также если при загрузке файла возникают другие проблемы, программа удаляет изображение с сервера и выводит на экран сообщение об ошибке.
-
Щелкните правой кнопкой мыши в редакторе Java и выберите "Fix Imports". В диалоговом окне "Fix Import" убедитесь, что java.io.File появляется в раскрывающемся списке файла, и нажмите кнопку "OK".
Это действие исправляет ошибки в коде.
Тестирование приложения
- Запустите приложение.
-
Нажмите кнопку "Browse" для поиска файла на локальных дисках и выберите графический файл для загрузки. Затем нажмите кнопку "Upload File".
На следующем рисунке показано приложение с загруженным файлом JPEG. Изображение сохраняется по пути project-directory\FileUploadExample\build\web\resources.

-
Введите текстовый файл в элемент "File Upload" и нажмите кнопку "Upload File". Убедитесь в том, что на экран выводится сообщение об ошибке.
Примечание: Визуализация элемента "File Upload" может быть различной, в зависимости от веб-обозревателя. Убедитесь, что этот элемент был протестирован в веб-обозревателях, которые предположительно установлены у пользователей.
Дополнительное упражнение 1: Загрузка текстового файла
Этот раздел является мини-руководством по загрузке текстового файла. В этом примере в элементе текстовой области на экран выводится содержимое файла, а в элементе группы сообщений – имя и размер файла. В этом примере содержимое файла не сохраняется. Для этого следует добавить код для сохранения файла на диске, как показано в предыдущем примере.
Примечание: В среде IDE NetBeans 6.1 поддерживается привязка по запросу. В тех местах, где элементы требуют написания кода Java, теперь следует вручную добавить атрибут привязки к элементам в визуальном веб-приложении JSF. Для этого щелкните правой кнопкой мыши каждый элемент и выберите "Add Binding Attribute". Для получения дополнительных сведений см. вики-страницу On-demand Binding Attribute.
- Создайте новый проект веб-приложения, в котором будет использоваться инфраструктура визуальных веб-приложений JavaServer Faces.
- Перетащите на страницу элемент "File Upload".
- Добавьте к этой странице элементы "Button", "Text Area" и "Message Group".
Примечание: В среде IDE NetBeans 6.1 поддерживается привязка по запросу. При использовании среды IDE NetBeans 6.1 следует вручную добавить атрибут привязки к элементам, которые будут представлены в коде Java. Для этого щелкните правой кнопкой мыши каждый элемент и выберите "Add Binding Attribute". Для получения дополнительных сведений см. вики-страницу On-demand Binding Attribute.
-
Дважды щелкните элемент "Button" и добавьте следующий код действия к методу 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: Изменение максимального размера загружаемого файла
Для загрузки файла размером больше одного мегабайта (например, большого графического файла, файла ZIP, JAR или исполняемого файла) следует изменить параметр maxSize для фильтра UploadFilter в файле приложения web.xml.
- Откройте окно "Files" и разверните имя_проекта > web > WEB-INF.
- Щелкните правой кнопкой мыши узел "web-xml" и выберите "Edit".
- В редакторе XML нажмите кнопку "Filters".
- Выберите параметр
maxSize для UploadFilter и нажмите кнопку "Edit".
-
В диалоговом окне установите требуемое значение "Param Value" и нажмите кнопку "OK".
Примечание: Из соображений безопасности не устанавливайте для параметра maxSize отрицательное значение, которое указывает, что ограничения по размеру файла отсутствуют.
- Для сохранения изменений выберите "File > Save".
Примечание: Если пользователь приложения пытается загрузить файл размером больше значения параметра maxSize, возникает следующее исключение, которое определяется как ошибка при проверке достоверности.
org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException
В итоговом сообщении, отображаемом у пользователей, указано:
No file was uploaded
В подробном сообщении указано:
No file was uploaded. The specified file exceeds the maximum allowable size of 1000000 Mb
Где 1000000 Mb является значением maxSize.
Дополнительное упражнение 3: Сохранение загруженных файлов в других местоположениях
В этом руководстве описана загрузка файла в папку веб-приложения /resources. Что делать, если требуется сохранить загруженные файлы в другом месте? Ниже приведены некоторые варианты.
Другая папка в веб-приложении
Изображения могут быть размещены в любом каталоге веб-приложения (т.е. любом каталоге под каталогом веб-приложения web). Например, можно создать подпапку upload/images под web и использовать следующий код для сохранения в ней изображений:
| Пример кода 6: код для загрузки файла в другую папку |
String realPath = theApplicationsServletContext.getRealPath("/upload/images");
File file = new File(realPath + File.separatorChar + justFileName);
|
Будьте внимательны при помещении загруженных файлов в веб-приложение, поскольку доступ к файлам по URL-адресу, например, по адресу http://localhost:29080/MyWebApplication/faces/upload/images/myPicture.gif, не ограничен.
Известный каталог на сервере
Для сохранения изображений где-либо в другом месте на сервере можно использовать, например, следующий код:
| Пример кода 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.
Пока еще не известный каталог
Существует другой вариант, при котором имя каталога помещается в дескриптор развертывания, что дает возможность динамического изменения местоположения.
- В окне "Files" разверните веб-узел, а затем разверните "WEB-INF". Для открытия дважды щелкните web.xml.
- Нажмите кнопку "General ", разверните "Context Parameters" и нажмите кнопку "Add".
-
Установите следующие значения, затем нажмите кнопку "OK".
Имя параметра: 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 первая загрузка изображения выполняется правильно. При второй загрузке изображения осуществляется обновление имени, типа и размера файла, но само изображение не обновляется. При перезагрузке страницы в обозревателе изображение отображается правильно.
- Имя графического файла должно содержать символы согласно ISO-8859-1.
Дополнительная информация
Дата последнего изменения страницы: 15 апреля 2008 г.