2

I'm writing this post because I need some help. I'm having trouble display an image depending on a specific path in my App.

Basically what it's doing: I have a module named Sector, and each Sector can have an image related to it. When I use the Upload component of Vaadin, I save the path of the image to a table in my database so that it can display the picture chosen before.

The actual path of the image is weird, it seems that Vaadin copies the image to a dynamic random folder. It seems logical that it can't use the actual path of the image.

But here's the problem: The path is well entered in the Database, but when I reload the page (F5), Vaadin can't shows the image anymore. Which upsets me since it should display it well.

The path that Vaadin creates with the uploaded image : VAADIN/dynamic/resource/2/c1ef7b9d-8f2b-4354-a97e-fe1fd4e868e7/551434.jpg

I can put some code if it can help.

The screenshots show what it's doing once I'm refreshing the browser page.

The image is being uploaded

After refreshing the page

Here is the part of the code where I handle the upload image:

upload.addSucceededListener(e -> {
            Component component = createComponent(e.getMIMEType(),
                    e.getFileName(), buffer.getInputStream());
            showOutput(e.getFileName(), component, output);
            //imgUpload = (Image) component;
            InputStream inputStream = buffer.getInputStream();
            targetFile = new File(PATH + currentProjetId + "\\secteur" + currentSecId + "\\photoSec.png");
            try {
                FileUtils.copyInputStreamToFile(inputStream, targetFile);
            } catch (IOException e1) {
                e1.printStackTrace();
                Notification.show("Error");
            }
            System.out.println("PATH : " + targetFile.getPath());
        });
Arthur
  • 23
  • 4

1 Answers1

3

I think you are using an in-memory resource that's discarded when you refresh the view. You have to take the contents of the file and save it in a file inside a directory in the server's file system. Here's an example:

FileBuffer receiver = new FileBuffer();
Upload upload = new Upload(receiver);
upload.setAcceptedFileTypes("text/plain");
upload.addSucceededListener(event -> {
    try {
      InputStream in = receiver.getInputStream();
      File tempFile = receiver.getFileData().getFile();
      File destFile = new File("/some/directory/" + event.getFileName());
      FileUtils.moveFile(tempFile, destFile);
      
    } catch (IOException e) {
      e.printStackTrace();
      Notification.show("Error").
    }
});
Alejandro Duarte
  • 1,365
  • 8
  • 15
  • Okay, thanks. I've succeeded in saving the image into a specific folder inside the app directory (actualy it's in src/main/resources/META-INF/resources/photos). I read on that [link](https://stackoverflow.com/questions/57553973/where-should-i-place-my-vaadin-10-static-files/57553974#57553974) that it was the place for static images. But I can't create an Image out of that path now. It's like it doesn't know where to look for the image. I can put some screens about the path and how I create the image if it helps you understand it. I'm sorry if my english isn't great. – Arthur May 06 '21 at 07:01
  • 1
    During project compilation `src/main/resources` is copied to the `target/classes` folder (in this case to `target/classes/META-INF/resources/photos`) so during execution you won't get the uploaded file as a resource through there. The file should be stored somewhere else on the file system and loaded from there and made into a `StreamResource` for serving during execution. – Mikael Grankvist May 06 '21 at 09:12
  • Okay, it's a bit blurry for me, would it be possible to have an example using the `StreamResource` thing? Because, from what I understand, I can't create an image from the copied File because it's not stored at a correct place. But where and how should I store it? – Arthur May 06 '21 at 11:07
  • The target file could be anywhere on the disk and then you can read it to a inputStream `File imageFile = new File("my/downloaded/file.jgp");` -> `InputStream targetStream = FileUtils.openInputStream(imageFile);` that is then used for the [StreamResource](https://vaadin.com/docs/v14/flow/advanced/tutorial-dynamic-content/#using-streamresource) – Mikael Grankvist May 06 '21 at 12:17
  • 1
    Okay so if I understand correctly: - When the user uploads an image, I copy the file to a directory `/home/user/photos` as an example. - I store the path of the File in my Database - When he goes to the view where I need to display the image: I create an `InputStream` with the image, to then use `StreamResource` to display the content Is that it? And if you know it, could you explain to me how to use that `StreamResource` ? Thanks by the way. – Arthur May 06 '21 at 12:46
  • Just look at the [documentation link](https://vaadin.com/docs/v14/flow/advanced/tutorial-dynamic-content#using-streamresource) and for instance at the [upload demo creating an image](https://github.com/vaadin/flow-components/blob/1c9206f420eb76d65a3131ee464ae99c5595b2a3/vaadin-upload-flow-parent/vaadin-upload-flow-demo/src/main/java/com/vaadin/flow/component/upload/demo/UploadView.java#L273) – Mikael Grankvist May 07 '21 at 03:43
  • You can find another example at https://vaadin.com/components/vaadin-image – Alejandro Duarte May 07 '21 at 06:18
  • Okay, I've succeeded in doing what I wanted. The fact is that I found a link about Vaadin 11, and it works on Vaadin 14. [Here](https://vaadin.com/forum/thread/17313780/vaadin-11-how-to-load-image-from-imputstream) it is. Thanks for your help guys. – Arthur May 07 '21 at 07:57
  • Good to hear! Thanks for sharing the rest of the solution. If the answer was useful, can you mark it as accepted, please? – Alejandro Duarte May 07 '21 at 10:42