33
25+ Reasons to use OmniFaces in JSF applications Anghel Leonard

25+ Reasons to use OmniFaces in JSF applications

Embed Size (px)

Citation preview

Page 1: 25+ Reasons to use OmniFaces in JSF applications

25+ Reasons to use OmniFaces in JSF applicationsAnghel Leonard

Page 2: 25+ Reasons to use OmniFaces in JSF applications

What we will cover ? (I)

• Enable restorable view• Loading CDN resources• Loading images as stream/byte array• OmniFaces converters• OmniFaces validators• OmniFaces server-side Cache• Defer JavaScript loading• Preserve view/request parameters on post-back• Execute JSF AJAX request via JavaScript method call• OmniFaces tree hierarchy • OmniFaces stateless ViewParam• Full AJAX exception handler• Highlight invalid inputs• OmniFaces boosted messages

Page 3: 25+ Reasons to use OmniFaces in JSF applications

What we will cover ? (II)

• Eagerly instantiate scoped beans• OmniFaces PartialViewContext• OmniFaces events for Invoke Application• Auto-generated JSF component IDs• Extensionless URLs• Import constants• Import functions• Combined resource handler• Unmapped resource handler• Injecting cookies and context params• OmniFaces filters• OmniFaces ViewScope• OmniFaces utilities methods• OmniFaces utilities functions

Page 4: 25+ Reasons to use OmniFaces in JSF applications

What is OmniFaces ?

• Well, if this is the first time when you hear about OmniFaces then you have to know that OmniFaces is a utility library for JSF and a comprehensive compendium of programming techniques, design patterns and recipes for JSF developers.

• Read before: Introduction to OmniFaces by Anghel Leonard

Page 5: 25+ Reasons to use OmniFaces in JSF applications

Enable restorable view

Your application works like a charm, but ViewExpiredException spoil all the satisfaction ?

OmniFaces fix this problem via a custom tag handler that instructs the view handler to recreate the entire view whenever the view has been expired. So, check how easy is to get rid of this exception using <o:enableRestorableView>.

Page 6: 25+ Reasons to use OmniFaces in JSF applications

Loading CDN resources

If you want to use <h:outputScript> and <h:outputStylesheet> to load external resources from CDNs (e.g. Google Hosted Libraries), then you know that this is not possible in default JSF ?

OmniFaces comes with the solution via a custom resource handler, named CDNResourceHandler. This will simply allows you to load resources from CDNs via <h:outputScript> and <h:outputStylesheet>.

Page 7: 25+ Reasons to use OmniFaces in JSF applications

Loading images as stream/byte array

You need to render images that comes as InputStream or byte[] ? You want to render them as data URI or load SVG files?

OmniFaces provides the <o:graphicImage>, which is an extension of the <h:graphicImage>  dedicated to render JSF resource as data URI, InputStream/byte[] property as resource, InputStream /byte[] property as data URI, etc. Just check the OmniFaces Showcase.

Page 8: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces converters

JSF custom converters are time consuming, they are called at every request regardless of whether the submitted value has changed or not, or they need to do the job based on possibly expensive service/DAO operations, etc.

Just if you read the names of converters provides out of the box by OmniFaces, you will take into account to check them at your first need to write a custom converter: 

GenericEnumConverterListConverter ListIndexConverterSelectItemsConverterSelectItemsIndexConverterValueChangeConverter

Read further: OmniFaces Converters by Constantin Alin

Page 9: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces validators

Components validation is interdependent ? Need special custom validators to:

- validate if ONLY ONE of the given UIInput components have been filled out ? - validate if ALL of the given UIInput components have been filled out ? - validate if ALL of the given UIInput components have the same value ?- validate if ONLY ONE of the given UIInput components has been filled out or that NONE of the given UIInput components have been filled out ? …

If you answered yes, or you think of some other case, then OmniFaces has a set of 14 special custom validators.

Read further: OmniFaces Validators by Anghel Leonard

Page 10: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces server-side Cache

Your page source code contains a lot of markup ? Well, the Render Response phase is the most time consuming JSF phase, especially in cases when the rendered markup is consistent.

You can speed up this process with a snap of a finger via the OmniFaces Cache component. Caching markup will boost the Render Response phase (check some tests here). The examples provided by OmniFaces Showcase are very clear and well explained.

Read further: Test OmniFaces Cache for Render Response Phase by Anghel Leonard

Page 11: 25+ Reasons to use OmniFaces in JSF applications

Defer JavaScript loading

 I know a trendy topic: deferred scripts. I'm pretty sure that you heard about placing the scripts at the end of </body>, use defer="true“ or async= "true", but I'm not so sure that you know that these approaches are not really working as expected.

The OmniFaces, <o:deferredScript> defers the loading of the given script resource to the window load event (the given script resource is only loaded when the window is really finished with loading).

Page 12: 25+ Reasons to use OmniFaces in JSF applications

Preserve view/request parameters on post-back

As you know, when we submit JSF forms we simply cannot preserveview or request parameters in the request URL.

Well, OmniFaces fixes this issue via Form (<o:form>) component, which extends the standard <h:form> and provides a way to keep view or request parameters in the request URL after a post-back and offers in combination with the <o:ignoreValidationFailed> tag on an UICommand component the possibility to ignore validation failures so that the invoke action phase will be executed anyway.

Page 13: 25+ Reasons to use OmniFaces in JSF applications

Execute JSF AJAX request via JavaScript method call

As an end-user you may want to execute a JSF AJAX request via a JavaScript function call. Well, OmniFaces provides the CommandScript component exactly for this purpose.

The <o:commandScript> is a component based on the standard <h:commandXxx> which generates a JavaScript function in the global JavaScript scope which allows the end-user to execute a JSF AJAX request by just a function call functionName() in the JavaScript context.

Page 14: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces tree hierarchy

OmniFaces comes with Tree component.

The <o:tree> allows the developers to have full control over the markup of a tree hierarchy by declaring the appropriate JSF components or HTML elements in the markup. The <o:tree> does namely not render any HTML markup by itself.

Beside the OmniFaces Showcase, you can check some examples here:

Use OmniFaces Tree to render JSONExpose a path as an OmniFaces tree (<o:tree>)Building dynamic responsive multi-level menus with plain HTML and OmniFaces

Page 15: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces stateless ViewParam

The JSF built-in <f:viewParam> is a stateful artifact. This causes major issues as Arjan Tijms points on his blog. OmniFaces, comes with a stateless ViewParam component.

The <o:viewParam> is a component that extends the standard <f:viewParam> and provides a stateless mode of operation and fixes the issue wherein null model values are converted to empty string parameters in query string (e.g. when includeViewParams=true) and the (bean) validation never being triggered when the parameter is completely absent in query string, causing e.g. @NotNull to fail.

Page 16: 25+ Reasons to use OmniFaces in JSF applications

Full AJAX exception handler

By default, most of AJAX exceptions are invisible to the client. They are returned to the client, but unfortunately JSF AJAX clients aren't prepared to deal with arbitrary error messages, so they simply ignore them. But a custom exception handler is specially created for this task by OmniFaces. The handler is named FullAjaxExceptionHandler, and the factory is named FullAjaxExceptionHandlerFactory. This will give to your AJAX based applications a real boost, because your end users would know if their actions was successfully performed or not.

Page 17: 25+ Reasons to use OmniFaces in JSF applications

Highlight invalid inputs

Beside validation messages, you simply want to highlight the invalid inputs of

a form via some CSS ?

The OmniFaces, <o:highlight> is a helper component which highlights all invalid UIInput components and the associated labels by adding an error style class to them. Additionally, it by default focuses the first invalid UIInput component.

Page 18: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces boosted messages

Working with <h:message> and <h:messages> has several important limitations.

 OmniFaces, comes with <o:messages>, which allows us to specify multiple client IDs space separated in the for attribute, show a single custom message whenever the component has received any faces message, HTML escaping and messages iteration markup control.

Page 19: 25+ Reasons to use OmniFaces in JSF applications

Eagerly instantiate scoped beans

CDI managed beans doesn’t have the ability to eagerly instantiate application scoped beans.

OmniFaces fills this void and even goes one step further by introducing the @Eager annotation that can be applied to @RequestScoped, @ViewScoped, @SessionScoped and @ApplicationScoped beans.

This causes these beans to be instantiated automatically at the start of each such scope instead of on demand when a bean is first referenced.

Page 20: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces PartialViewContext

Do you need to:

• Execute callback scripts by PartialResponseWriterstartEval() ?

• Add arguments to AJAX response ?• Prevents errors about malformed XML caused by tags which

Mojarra and MyFaces has left open after an exception in rendering of an already committed AJAX response ?

• Fix the no-feedback problem when a ViewExpiredException occurs during an AJAX request on a page which is restricted by web.xml <security-constraint> ?

Then you need the OmniFaces, OmniPartialViewContext.

Page 21: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces events for Invoke Application

JSF comes with a considerable number of events, but none of them is related to Invoke Application phase.

OmniFaces fills this void with the InvokeActionEventListener which add support for the new <f:event> types: preInvokeAction and postInvokeAction. Those events are published during the beforephase and afterphase of INVOKE_APPLICATION respectively. This actually offers a better hook on invoking actions after the <f:viewParam> values been set than the preRenderView event.

Starting with OmniFaces 2.2, any component will support these two events.

Page 22: 25+ Reasons to use OmniFaces in JSF applications

Auto-generated JSF component IDs

As you know, JSF will provide auto-generated IDs for each component that doesn’t have an explicit ID.

OmniFaces has an view handler, NoAutoGeneratedIdViewHandler which inspects the rendered output and signal via an llegalStateException whenever an automatically generated JSF component ID (j_id...) is encountered in the rendered output.

Page 23: 25+ Reasons to use OmniFaces in JSF applications

Extensionless URLs

Do you find the presence of the extension (e.g. .xhtml) inappropriate in the URL ?

Well, OmniFaces comes with FacesViews, which is a mechanism to use SEO-friendly extensionless URLs in a JSF application without the need to enlist individual Facelet source files in some configuration file.

Instead, Facelets source files can be put into either the special /WEB-INF/faces-views directory, from where they will be automatically scanned (no configuration whatsoever required) or an explicit directory can be configured to be scanned. The web app root is supported as well.

Page 24: 25+ Reasons to use OmniFaces in JSF applications

Import constants

By default, constant field values cannot be use in JSF pages.

Well, OmniFaces provides the ImportConstants tag handler that allows the developer to have a mapping of all constant field values of the given fully qualified name of a type in the request scope (e.g. declared as, public static final).

Page 25: 25+ Reasons to use OmniFaces in JSF applications

Import functions

By default, functions that are not registered in .taglib.xml file cannot be use in JSF pages.

Well, OmniFaces comes with the ImportFunctions tag handler which allows developers to have access to all functions of the given fully qualified name of a type in the Facelet scope using the usual EL functions syntax without the need to register them in .taglib.xml file. The functions are those public static methods with a non-void return type.

Page 26: 25+ Reasons to use OmniFaces in JSF applications

Combined resource handler

As you know, for each resource (CSS and JS) we have a separate request. OmniFaces seriously improve the page loading speed via the CombinedResourceHandler resource handler.

This will remove all separate script and stylesheet resources which have the target Attributeset to head from the UIViewRoot and create a combined one for all scripts and another combined one for all stylesheets.

Page 27: 25+ Reasons to use OmniFaces in JSF applications

Unmapped resource handler

When we need to reference relative URLs to images in CSS files we can use the #{resource} EL expression in images paths. This issue is solved by OmniFaces via the UnmappedResourceHandler.

This implementation allows the developer to map JSF resources on an URL pattern of /javax.faces.resource/* without the need for an additional FacesServlet prefix or suffix URL pattern in the default produced resource URLs.

Page 28: 25+ Reasons to use OmniFaces in JSF applications

Injecting cookies and context params

Need quick access to information stored in cookies and context parameters ? Preferably via CDI injection ?

Well, OmniFaces provides @Cookie annotation for injecting cookie data and @ContextParam annotation for injecting context parameters (the later is available starting with OmniFaces 2.2).

Page 29: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces filters

OmniFaces comes with several filters, as follows:

• CacheControlFilter - controls the cache-related headers of the response

• CharacterEncodingFilter - set the request body character encoding when not already set by the client

• FacesExceptionFilter - solve 2 problems with exceptions thrown in JSF methods: Mojarra's FacesFileNotFoundException needs to be interpreted as 404 and root cause needs to be unwrapped from FacesException and ELException to utilize standard Servlet API error page handling.

• GzipResponseFilter - will apply GZIP compression on responses whenever applicable

• HttpFilter - abstract filter specifically for HTTP requests

Page 30: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces ViewScope

OmniFaces comes with a view scope that can be used in JSF 2.0/2.1.

Starting with JSF 2.2, we can use the built-in view scope, but, if we need to immediately destroy @ViewScoped bean when browser window is unloaded /closed then we need to come back to OmniFaces solution.

Starting with OmniFaces 2.2, the view scope was improved to immediately destroy @ViewScoped on a GET navigation, or a close of browser tab

/window. These features are not supported by JSF 2.2.

Page 31: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces utilities methods

OmniFaces comes with 300+ utilities methods that are available in org.omnifaces.util package. We have utility methods based on JSF API for AJAX, CDI Beans, messages, faces, events, callbacks, renderers, etc. Most of them are useful to obtain a less verbose code, much easy to understand, others provides hidden functionalities or simply comes with new functionalities that are not easy to be achieved in JSF.

Read further: OmniFaces Utilities ZEEF Page by Anghel Leonard

Page 32: 25+ Reasons to use OmniFaces in JSF applications

OmniFaces utilities functions

OmniFaces comes with a comprehensive set of utilities functions in org.omnifaces.el.functions package. These functions allows us to easy manipulate objects, strings, arrays, dates, numbers, etc directly in page via EL.

Read further: OmniFaces Utilities ZEEF Page by Anghel Leonard

Page 33: 25+ Reasons to use OmniFaces in JSF applications

References

• Bauke Scholtz - http://balusc.omnifaces.org/• Arjan Tijms - http://arjan-tijms.omnifaces.org/• JSF ZEEF page  - https://jsf.zeef.com/bauke.scholtz• OmniFaces ZEEF page - https://omnifaces.zeef.com/bauke.scholtz• OmniFaces Wikipedia - http://en.wikipedia.org/wiki/OmniFaces