user1068477
user1068477

Reputation:

Vaadin Upload filestream no close?

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:

  1. Why no fos.close() anywhere (in finally block)?
  2. Why in the world is OutputStream returned from the method? Especially when the receiver is being passed into a Listener? Is the Listener closing the stream?
  3. Where do I close the stream?

Upvotes: 0

Views: 441

Answers (1)

Morfic
Morfic

Reputation: 15518

If you look at the sources you will see that:

  1. Why no fos.close() anywhere (in finally 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).

  1. Why in the world is OutputStream returned from the method? Especially when the receiver is being passed into a Listener? 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 written
  • SucceededListener - receives notification when the upload has been completed successfully

Hence 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.

  1. 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

Related Questions