Пост самому себе на заметку. Недавно мне нужно было добавить в Vaadin портлет (Liferay 6.0.6 на Glassfish 3.1.1) возможность загрузки файлов на сервер. С точки зрения программирования это тривиальная задача, однако, без небольшого шаманства портлет не заработал.
Код, осуществляющий загрузку, выглядит следующим образом:
public class ApplicationForm extends Form implements Upload.SucceededListener,
Upload.FailedListener,
Upload.Receiver {
File file; // File to write to.
ArrayList<File> attachments = new ArrayList<File>();
ArrayList<Label> labels = new ArrayList<Label>();
private Upload upload = new Upload(LocalizationUtil.getString("form.attach.title"), this);
public ApplicationForm(Application app, String path) {
// Listen for events regarding the success of upload.
upload.setButtonCaption(LocalizationUtil.getString("form.attach"));
upload.addListener((Upload.SucceededListener) this);
upload.addListener((Upload.FailedListener) this);
this.getLayout().addComponent(upload);
}
// Callback method to begin receiving the upload.
public OutputStream receiveUpload(String filename, String MIMEType) {
FileOutputStream fos = null; // Output stream to write to
try {
file = new File("...your path..." + filename);
// Open the file for writing.
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
// Error while opening the file. Not reported here.
e.printStackTrace();
return null;
}
return fos; // Return the output stream to write to
}
// This is called if the upload is finished.
public void uploadSucceeded(Upload.SucceededEvent event) {
// Log the upload on screen.
Label tmp = new Label("Файл " + event.getFilename() + " успешно загружен.");
this.getLayout().addComponent(tmp);
labels.add(tmp);
attachments.add(file);
}
// This is called if the upload fails.
public void uploadFailed(Upload.FailedEvent event) {
// Log the failure on screen.
Label tmp = new Label("При загрузке " + event.getFilename() + " произошла ошибка.");
this.getLayout().addComponent(tmp);
labels.add(tmp);
}
}
В результате мы получим такой компонент:

Чтобы использовать компонент Upload
, необходимо определить класс, который реализует интерфейс Upload.Receiver
. Метод receiveUpload()
будет вызван когда пользователь нажмет на кнопку Submit.Также этот класс реализует интерфейсы Upload.SucceededListener
и Upload.FailedListener
, поэтому в зависимости от результата загрузки будут вызваны методы uploadSucceeded
или uploadFailed.
Приведенный выше пример не заработал, при нажатии кнопки submit страница обновлялась и файл не загружался. При этом в логе никаких ошибок не было.
Как выяснилось, проблема была в несовместимоти widgetset'ов и тем Vaadin, которые использовались в портлете и в Liferay. В портлете использовалась версия Vaadin 6.6.2, поэтому widgetset'ы и темы Liferay нужно было обновить до этой версии. Их можно скачать здесь - http://vaadin.com/download/release/6.6/6.6.2/other/. Затем нужно скопировать содержимое zip архива в каталог html сервера, в моем случае путь к нему выглядел так: ~/glassfish3/glassfish/domains/domain1/applications/liferay-portal-6.0.6-20110225/html
После этого загрузка работает без проблем. Widgetset'ы и темы для других версий Vaadin также можно найти по этой ссылке - http://vaadin.com/download/release/