How to show pdf file in filestorage in jmix flow

How can I show pdf file saved in filestorage in iframe in jmix flow 1.1.

I checked following post but unable to made it working.

Thanks

I am using this code -


 FileStorage fileStorage = fileStorageLocator.getDefault();
                FileRef fd = event.getItem().getFile();
                String fileName = fd.getFileName();
                try {
                    byte[] pdf = fileStorage.openStream(fd).readAllBytes();
                    ByteArrayInputStream in = new ByteArrayInputStream(pdf);
                    StreamResource resource2 = new StreamResource(fileName, () -> in);
                    frame1.setSrc(resource2.toString());
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }

but nothing show in iframe and no error.

Please guide.

Hi,

resource2.toString() returns something like com.vaadin.flow.server.StreamResource@795b49bb which is not a resource url.

The correct code is:

private void updateDocFrame() {
    FileRef document = getEditedEntity().getDocument();
    if (document == null) {
        return;
    }

    try (InputStream inputStream = fileStorage.openStream(document)) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(inputStream.readAllBytes());
        StreamResource resource = new StreamResource(document.getFileName(), () -> byteArrayInputStream);
        StreamRegistration registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);
        docFrame.setSrc(registration.getResourceUri().toString());
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

Also you need to allow FrameOptions. To do this, add CustomSecurityConfiguration class:

@EnableWebSecurity
@Configuration
public class CustomSecurity extends FlowuiSecurityConfiguration {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin));
    }
}

Regards,
Gleb

Thanks gorelov,

I was able to solve issue by following code -

try {
InputStream ss = fileStorage.openStream(fd);
StreamResource resource = new StreamResource(fileName,
() → ss);
resource.setContentType(“application/pdf”);
StreamRegistration registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);
frame1.setSrc(registration.getResourceUri().toString());
frame1.setSizeFull();
} catch (Exception e) {
System.out.println(e.getMessage());
}

and this in securituy-

@EnableWebSecurity
public static class DefaultFlowuiSecurityConfiguration extends FlowuiSecurityConfiguration {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.headers(headers ->
                headers.contentSecurityPolicy(secPolicy ->
                        secPolicy.policyDirectives("frame-ancestors localhost:8080")
                )
        );
    }
}

Thanks again

Regards

Umesh

PS: checked and varified your code and it is working fine. Shifting to your code. thanks

Sorry to revive this post but I have actually tried two different ways to do it and have not been able to solve it.
I tried this way and it doesn’t display anything.
Then I found this post and everything seems to work, but it is not able to give me access to the file to display it.

@EnableWebSecurity
@Configuration
public class IframeCustomSecurity extends FlowuiSecurityConfiguration {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin));
    }
}

After the user logs in the system checks if he/she already has an accepted license and data handling agreement, if not then it should display the pdf

var fileRef = licenseOfUse.getUsePolicy().getFileRef();
try (var inputStream = fileStorage.openStream(fileRef)) {
                    var byteArrayInputStream = new ByteArrayInputStream(inputStream.readAllBytes());
                    var resource = new StreamResource(fileRef.getFileName(), () -> byteArrayInputStream);
                    resource.setContentType("application/pdf");
                    var registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);

                    var frame = components.create(IFrame.class);
                    frame.setWidth("100%");
                    frame.getStyle().set("border", "unset");
                    frame.setSrc(registration.getResourceUri().getPath());

                    dialogs.createOptionDialog()
                            .withHeader(messages.getMessage("com.trezetech.mediesfera.view.main/LicenseAcceptedByUser.header"))
                            .withContent(frame)
                            .withActions(
                                    new DialogAction(DialogAction.Type.NO)
                                            .withHandler(e -> logoutButton.click()),
                                    new DialogAction(DialogAction.Type.YES)
                                            .withHandler(e -> licenseQry.saveLicenseOfUse(licenseOfUse))
                            )
                            .withWidth("45em")
                            .withHeight("55em")
                            .open();
                } catch (IOException ex) {
                    throw new ResourceException("An error occurred while trying to read the resource: {}", ex);
                }

Is just not able to display it, maybe I’m missing a step that I can’t see to finish the process correctly.

image

Any suggestions,

Nelson F.

Any suggestions on how to fix this?

Hi,

Could you please attach a small demo project that reproduces the problem?

Gleb

Hi, attached is a brief example of the situation.
example.zip (138.2 KB)

Hi,

After investigation, it appears that StreamRegistration generated by VaadinSession.getCurrent().getResourceRegistry().registerResource(resource) doesn’t work in a dialog windows. The same code works if an iframe in MainView’s initial layout. Seems like a Vaadin bug.

Regards,
Gleb

1 Like

Thank you for your response. I will look for another way to implement it.

I recommend Vaadin addon - Pdf Viewer - Vaadin Add-on Directory