I am trying to evaluate if it is possible to add Progressive Web App support to a JavaServerFaces web application. Our JSF app is has grown over the years and a possible future requirement might be to make parts of the application available for offline use. Besides the other nice features offered by PWA functionality (notifications, full screen web app, add to homescreen, etc), we would be primarily interested in the offline capabilities that PWA in conjunction with a service worker and caching seems to offer.
Our clients have to work in areas where sometimes there is no internet connection available. In such a situation, they should ideally be able to have access the app, authenticate themselves and navigate to the part of the app they need to use on-sight. In this part of the app they would manipulate or create new datasets. If I am informed correctly, one can - in theory - use the PWA service worker to cache data and even to store newly created or updated data for a later synchronisation with the server. Is this the case?
While the idea of PWA support seems nice, I have serious doubts that it is possible to implement especially the offline mode capabilities in a JSF application, since all the application logic is basically on the server side and the client does not make direct API calls to GET/POST/PUT/etc (and hence cache and synchronize) the data.
My research so far has produced nothing substantial (JSF & PWA) which is the reason why I am posting this question. It would be great if someone could point me into the right direction or give me an answer if JSF apps can make use of the PWA technologies, especially the offline/caching/synchronisation functionality.
Thank you.
Since version 3.7, OmniFaces adds PWA support to a certain degree via the built-in PWAResourceHandler. The usage is well documented and demonstrated in the showcase.
First create a class which extends from WebAppManifest
public class YourWebAppManifest extends WebAppManifest {
}
Give it a CDI scope annotation matching its state, e.g. @ApplicationScoped.
@ApplicationScoped
public class YourWebAppManifest extends WebAppManifest {
}
Override/implement properties conform their Javadoc and rules in W3 spec.
@ApplicationScoped
public class YourWebAppManifest extends WebAppManifest {
@Override
public String getName() {
return "Your Application";
}
@Override
public Collection<ImageResource> getIcons() {
return Arrays.asList(
ImageResource.of("logo.svg"),
ImageResource.of("logo-120x120.png", Size.SIZE_120),
ImageResource.of("logo-180x180.png", Size.SIZE_180),
ImageResource.of("logo-192x192.png", Size.SIZE_192),
ImageResource.of("logo-512x512.png", Size.SIZE_512)
);
}
@Override
public String getOfflineViewId() {
return "/offline.xhtml";
}
}
Reference it in your HTML head as follows, with the exact library name omnifaces and resource name manifest.json:
<link rel="manifest" href="#{resource['omnifaces:manifest.json']}" />
That's basically it. The PWAResourceHandler will automatically generate the desired manifest.json and sw.js files and serve the /offline.xhtml template as offline view.
By default, all <welcome-file> entries in web.xml are registered as "cacheable resources", i.e. they are also available offline. You can override this in your custom WebAppManifest as follows:
@Override
public Collection<String> getCacheableViewIds() {
return Arrays.asList("/index.xhtml", "/contact.xhtml", "/support.xhtml");
}
You'll probably also want to make all JSF forms in these pages stateless by using <f:view transient="true"> so that they don't throw a ViewExpiredException.
The major advantage of this PWAResourceHandler is primarily that you don't need to manually fabricate the sw.js, but can just control its contents/configuration via a simple CDI bean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With