私は Vaadin 7 CookBook から Vaadin を学んでいます。第 3 章では、著者が StreamVariable と Html5File を使用したドラッグ アンド ドロップ アップローダの例を示しています。コードは次のとおりです。
public class DragAndDropUploader extends VerticalLayout {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String REPOSITORY = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath()+"/WEB-INF/vaadin-repo/";
public DragAndDropUploader() {
final Table table = new Table();
table.setSizeFull();
table.addContainerProperty("File name", String.class, null);
table.addContainerProperty("Size", String.class, null);
table.addContainerProperty("Progress", ProgressBar.class, null);
DragAndDropWrapper dropTable = new DragAndDropWrapper(table);
dropTable.setDropHandler(new DropHandler() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void drop(DragAndDropEvent event) {
WrapperTransferable transferred = (WrapperTransferable) event.getTransferable();
Html5File[] files = transferred.getFiles();
if (files != null) {
for (Html5File file : files) {
ProgressBar progressBar = new ProgressBar();
progressBar.setSizeFull();
UI.getCurrent().setPollInterval(100);
table.addItem(new Object[] { file.getFileName(),
getSizeAsString(file.getFileSize()),
progressBar
}, null);
StreamVariable streamVariable = createStreamVariable(file, progressBar);
file.setStreamVariable(streamVariable);
}
}
else {
Notification.show("Usupported file type", Type.ERROR_MESSAGE);
}
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
});
addComponent(dropTable);
setSizeUndefined();
}
private StreamVariable createStreamVariable(final Html5File file, final ProgressBar progressBar) {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
return new StreamVariable() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void streamingStarted(StreamingStartEvent event) {
}
@Override
public void streamingFinished(StreamingEndEvent event) {
try {
FileOutputStream fos = new FileOutputStream(REPOSITORY+file.getFileName());
System.out.println(outputStream.size()+ ": "+outputStream.toString() + " - " +fos.toString());
outputStream.writeTo(fos);
} catch (IOException e) {
Notification.show("Streaming finished failing, please, retry", Type.ERROR_MESSAGE);
}
progressBar.setValue(new Float(1.0));
}
@Override
public void streamingFailed(StreamingErrorEvent event) {
Notification.show("Streaming failed, please, try again", Type.ERROR_MESSAGE);
}
@Override
public void onProgress(StreamingProgressEvent event) {
progressBar.setValue((float) event.getBytesReceived() / file.getFileSize());
}
@Override
public boolean listenProgress() {
return true;
}
@Override
public boolean isInterrupted() {
return false;
}
@Override
public OutputStream getOutputStream() {
return outputStream;
}
};
}
private String getSizeAsString(long size) {
String unit = "B";
int kB, MB;
if (size >= (kB = (2 << 10))) {
size = size / kB;
unit = "kB";
}
else if (size >= (MB = 2 << 20)) {
size = size / MB;
}
return size + " " + unit;
}
}
REPOSITORY は、 内の vaadin-repo フォルダーへのパスWebContent/WEB-INF
です。
私の問題はoutputStream.writeTo(fos);
、実際にファイルをサーバーに書き込む必要がある場所です。
@Override
public void streamingFinished(StreamingEndEvent event) {
try {
FileOutputStream fos = new FileOutputStream(REPOSITORY+file.getFileName());
System.out.println(outputStream.size()+ ": "+outputStream.toString() + " - " +fos.toString());
outputStream.writeTo(fos);
} catch (IOException e) {
Notification.show("Streaming finished failing, please, retry", Type.ERROR_MESSAGE);
}
progressBar.setValue(new Float(1.0));
}
しかし、そうではありません。アップロードしてからそのvaadin-repo
フォルダを確認すると、空のままです...
例外は発生しません (FileNotFoundException も IOException もありません) ので、問題はそれではありません。REPOSITORY パスにはいくつかのスペースがあります (ただし、これは問題ではないと思います (FileNotFoundException が発生しないと言ったように)、以前に Vaadin のアップローダーを実装しました ( Upload.Receiver内部インターフェイスを介して))。
問題はどこだ?