Happy New Year! OmniFaces 1.7 has yesterday been released!
Again, this release had some unscheduled delay for various reasons. Among others, I migrated back from CuraƧao to the Netherlands and Arjan Tijms moved into a new home, resulting in both having much less free time during the same period. This also explains why there are relatively small additions and changes in this release. The three most useful additions are the fixviewstate.js
, CacheControlFilter
and <o:validateMultiple>
.
Fix JSF view state after ajax-rendering content which contains another form
You'll probably recognize the Mojarra-related problem described in an earlier blog Communication in JSF 2.0 - Ajax rendering of content which contains another form. In short, when you ajax-render some component which in turn contains another form, then this form would lose its JSF view state hidden field which in turn causes that the 1st submit always misses hit and only the 2nd submit works. This problem was almost 4 years ago reported as JSF spec issue 790 and for a long time scheduled to be fixed for JSF 2.2, however for some unclear reason it has been postponed to JSF 2.3. Note: early MyFaces 2.0.x/2.1.x versions also exposed this problem, but they internally fixed it rather quickly irrespective of the spec issue being targeted at 2.2/2.3.
Even though this problem could be fixed by a custom jsf.ajax.addOnEvent
script, the script is relatively large and sensitive to minor browser-specific bugs and thus not really worth copypasting plain into every single new JSF project. We couldn't wait any longer for JSF 2.3, so it has been added to OmniFaces 1.7! Long story short, you can see it in action at the showcase. It's basically a matter of adding the following line inside the <h:body>
(not head!) of your master template:
<h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
Note for PrimeFaces users: this script also silently fixes a minor PrimeFaces-related bug in versions older than 3.5.23 and 4.0.7: its internal fix for this problem namely incorrectly appends the JSF view state hidden field to GET forms as well! The fixviewstate.js
removes the hidden field from those forms afterwards. By the way, speaking about PrimeFaces, the showcase application has for this release been upgraded from PrimeFaces 3.5 to 4.0. No single change was necessary in the UI side (XHTML/CSS/JS). Kudos! In the Java side (backing beans, etc) only the Constants#VERSION
was removed, but that's not really relevant for the average PrimeFaces based webapp.
Control cache-related response headers
One of the more common homegrown servlet filters is one which sets the Cache-Control
, Expires
and Pragma
headers related to browser caching. With the new CacheControlFilter
there's now finally one more "standard" OmniFaces solution to minimize repeatedly homegrown code in your JSF project. Its configuration is relatively simple, in order to disable caching on all dynamic JSF pages, just add the following to the project's web.xml
, assuming that your FacesServlet
is mapped with a <servlet-name>
of facesServlet
:
<filter>
<filter-name>noCache</filter-name>
<filter-class>org.omnifaces.filter.CacheControlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>noCache</filter-name>
<servlet-name>facesServlet</servlet-name>
</filter-mapping>
If you want to cache resources matching an example URL pattern of /foo/*
for 2 days, then map it so, with an expires
initialization parameter which can take a value of a number with a "w", "d", "h", "m" or "s" suffix indicating respectively weeks, days, hours, minutes or seconds:
<filter>
<filter-name>cache2days</filter-name>
<filter-class>org.omnifaces.filter.CacheControlFilter</filter-class>
<init-param>
<param-name>expires</param-name>
<param-value>2d</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cache2days</filter-name>
<url-pattern>/foo/*</url-pattern>
</filter-mapping>
Note that you can easily specify multiple <url-pattern>
entries in a single <filter-mapping>
. See also the showcase.
Validate multiple input fields in a single method
If no one of the existing multi field validators <o:validateAll>
, <o:validateAllOrNone>
, <o:validateEqual>
, <o:validateOne>
, <o:validateOneOrMore>
, <o:validateOneOrNone>
, <o:validateOrder>
or <o:validateUnique>
is sufficient for your concrete functional requirement, then you have now the opportunity to easily implement your custom multi field validation method via the new <o:validateMultiple>
tag. Here's an example referencing a bean method:
<o:validateMultiple id="myId" components="foo bar baz" validator="#{bean.someMethod}" />
<h:message for="myId" />
<h:inputText id="foo" />
<h:inputText id="bar" />
<h:inputText id="baz" />
Whereby the method has the following signature (method name is free to your choice):
public boolean someMethod(FacesContext context, List<UIInput> components, List<Object> values) {
// ...
}
You've all input values at your hands in a single place whereby you just return true
when the specific combination of those values is considered valid based on your own business requirements. See also the showcase which shows a slight different example referencing a backing bean implementing MultiFieldValidator
interface. Thanks goes to OmniFaces user Juliano Marques for the kickoff implementation of the component and taghandler for this.
An overview of all additions/changes/bugfixes in OmniFaces 1.7
Taken over from the What's new? page on showcase:
Added in OmniFaces 1.7
- New
omnifaces:fixviewstate.js
script which should automatically fix JSF issue 790 - Added
invalidateAll
attribute to disable invalidating valid fields, and add support forshowMessageFor="@invalid"
to show message for invalidated fields only - New
ValueChangeValidator
which runs only when the submitted and converted value is really changed as compared to the model value - Added
Faces#getBookmarkableURL()
methods takingParamHolder
instances as value - Added
Beans#getInstance()
andBeans#getActiveInstances()
methods returning concrete (non-proxied) instances - New
CacheControlFilter
which can control cache-related headers of the response - New
<o:validateMultiple>
tag which allows validating multiple fields via a custom validator method or implementation - Added
WebXml#getSessionTimeout()
to get web.xml configured session timeout - Added
SortedTreeModel
which holds the<o:tree>
children in aTreeSet
Changed in OmniFaces 1.7
FullAjaxExceptionHandler
is now able to handle error in error page itself
Fixed in OmniFaces 1.7
- Store constants of
<o:importConstants>
in an ordered map instead of an unordered map WebXml
initialization failed in Weblogic because it attempts to load it as CDI managed bean- Broken 404 "not found" error handling of
CombinedResourceHandler
(it threwIllegalArgumentException
instead) GenericEnumConverter
failed in composites which are reused more than once in same view and on enums with custom bodies<o:validateOrder>
threw NPE on non-required fields
Maven download stats
Here are the Maven download stats:
- September 2013: 1779
- October 2013: 3202
- November 2013: 2091
- December 2013: 2344
11 comments:
hey, Bauke!
Congrats on the release, man.
Best of luck in the new-old life at Netherlands. =)
Cheers,
Elias
@elias, thank you, your wish is very much appreciated. It ain't easy; my life is basicaly turned upside down.
Hey Bauke, great job. Good luck in your new path. :)
Are you ever going to do something portlet-related? You can't imagine how broken some things are, and I'm sure you'd be of great help!
@Rinaldo: thank you! As to portlets, as long as I don't encounter portlets in my job path, I don't think I will ever do something with them. Sorry! :)
Great! As a myfaces 2.2 user who also uses PF 4, should i use the fix script? Or rather when is adding it a good idea?
@Karl: only if you also have plain HTML GET forms in your JSF page. In such case, PF will incorrectly add JSF view state to them as well which will cause an undesired additional javax.faces.ViewState parameter in the URL after submit.
Congrats on the release!!!
@Karl @Bauke, we've fixed the minor bug on PF 5.0, 3.5.23 and 4.0.7 on our side as well, so GET forms do not get view state anymore.
@cagatay: that's great!
Hey.
I'm use omnifaces 1.7.
There is a reason why o:messages does not work inside a composite component ?
h:message(s) works, but it not easily stylist.
Thanks.
@Welyab: a related bug was fixed for 1.8. Can you please try 1.8 snapshot instead?
Thanks BalusC! This bug is so much PITA :)
Post a Comment