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
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.
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,
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
Thank you for your response. I will look for another way to implement it.