Reputation:
Vaadin 7.6.2
From this doc, comes this code example: https://vaadin.com/docs/-/part/framework/components/components-upload.html
// Show uploaded file in this placeholder
final Embedded image = new Embedded("Uploaded Image");
image.setVisible(false);
// Implement both receiver that saves upload in a file and
// listener for successful upload
class ImageUploader implements Receiver, SucceededListener {
public File file;
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
FileOutputStream fos = null; // Stream to write to
try {
// Open the file for writing.
file = new File("/tmp/uploads/" + filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
new Notification("Could not open file<br/>",
e.getMessage(),
Notification.Type.ERROR_MESSAGE)
.show(Page.getCurrent());
return null;
}
return fos; // Return the output stream to write to
}
public void uploadSucceeded(SucceededEvent event) {
// Show the uploaded file in the image viewer
image.setVisible(true);
image.setSource(new FileResource(file));
}
};
ImageUploader receiver = new ImageUploader();
// Create the upload with a caption and set receiver later
Upload upload = new Upload("Upload Image Here", receiver);
upload.setButtonCaption("Start Upload");
upload.addSucceededListener(receiver);
// Put the components in a panel
Panel panel = new Panel("Cool Image Storage");
Layout panelContent = new VerticalLayout();
panelContent.addComponents(upload, image);
panel.setContent(panelContent);
I have a few questions regarding this:
fos.close()
anywhere (in finally
block)?OutputStream
returned from the method? Especially when the receiver
is being passed into a Listener? Is the Listener closing the stream?Upvotes: 0
Views: 441
Reputation: 15518
If you look at the sources you will see that:
- Why no
fos.close()
anywhere (infinally
block)?
Because it's not up to you to close the output stream. The framework will handle reading the data it receives, writing it to file and closing the stream (even when something goes wrong). This happens in FileUploadHandler
in the streamToReceiver()
method (line 529 in the current version).
- Why in the world is
OutputStream
returned from the method? Especially when thereceiver
is being passed into aListener
? Is the Listener closing the stream?
Because the sole purpose of the Receiver
is to tell the framework where it should write the data it receives. From the docs:
/**
* Interface that must be implemented by the upload receivers to provide the
* Upload component an output stream to write the uploaded data.
*
* @author Vaadin Ltd.
* @since 3.0
*/
To further shed some light over the confusion of the receiver
being passed into a Listener
: it is not. The ImageUploader
implements both
Receiver
- provides output stream where the content should be writtenSucceededListener
- receives notification when the upload has been completed successfullyHence the same ImageUploader
instance is passed both in the constructor of the Upload
component where it will be used as a Receiver
, and in the addSucceededListener()
method where it will be used as a... you guessed it, SucceededListener
. Most people (probably?!) prefer to implement all those interfaces together in the same class, but you can choose to implement each of the functionality in their own class if you so desire, then pass an an appropriate instance to each method.
- Where do I close the stream?
You don't, the framework will close it for you when the upload is finished just as explained at point 1. And in the meantime, you can go grab a beer :-)
Upvotes: 2