Update 21 sep 2016: Oops, I made a mistake in <o:validateBean>
class level validation. OmniFaces 2.5.1 has therefore been released!
OmniFaces 2.5 2.5.1 has been released!
The major visible changes are the <o:inputFile>
component which extends and improves <h:inputFile>
, the @GraphicImageBean
annotation which can be used to mark a bean as a public and dedicated image service, and adoption of "MultiViews" in FacesViews.
The major invisible changes are removal of CDI 1.0 targeted workarounds (including the deprecation of org.omnifaces.config.BeanManager
enum), intergration of Travis CI and addition of several integration tests based on JUnit/Arquillian/Selenium/Graphene. As of now, @ViewScoped
, @Eager
, FullAjaxExceptionHandler
, FacesViews
and CombinedResourceHandler
have IT cases which are run against WildFly 10.0.0, TomEE 7.0.1 and Payara 4.1.1.163.
You can find the complete list of additions, changes and fixes at What's new in OmniFaces 2.5.1? list in showcase.
Installation
Non-Maven users: download OmniFaces 2.5.1 JAR and drop it in /WEB-INF/lib
the usual way, replacing the older version if any.
Maven users: use <version>2.5.1</version>
.
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>2.5.1</version>
</dependency>
For CDI-less users, there will be no version 1.15. There are no major 2.x bugfixes anymore which should also end up in 1.1x. Therefore it isn't worth the effort to merge 2.x back to 1.1x again. And, due to major changes in 2.x project structure, merging 2.x branch back to 1.1x branch has become a tedious task which isn't worth the effort anymore. OmniFaces 1.1x is now in maintenance mode. The latest 1.1x version is still 1.14. Of course there may be bugfix releases in the future, but so far there are no major 2.4-2.5 bugs which also affect 1.14, so there's no 1.14.1 yet as of now.
If you need some arguments to move to CDI:
- Upcoming JSF 2.3 will require a CDI dependency
- JSF own @ManagedBean and @XxxScope annotations are marked deprecated in JSF 2.3 (already as of 2.3-m06)
- Spring 3.x already supports javax.inject API from CDI, so Spring services (which are often used to substitute the lack of EJB support in Tomcat) can seamlessly be injected in CDI managed beans.
Multi file upload with builtin file type and size validation
The relatively new <h:inputFile>
component, which was introduced only in JSF 2.2, has been extended and enhanced into new <o:inputFile>
component with support for multiple file selection and folder selection via new HTML5 multiple
and directory
attributes.
<h:form enctype="multipart/form-data">
<o:inputFile value="#{bean.files}" multiple="true" />
<h:commandButton value="Upload" action="#{bean.upload}" />
</h:form>
private List<Part> files; // +getter+setter
public void upload() {
if (files != null) {
for (Part file : files) {
String name = Servlets.getSubmittedFileName(file);
String type = file.getContentType();
long size = file.getSize();
InputStream content = file.getInputStream();
// ...
}
}
}
Also, media type filtering via new HTML5 accept
attribute has been added, along with built-in server side validation based on file extension. The below example will in modern browsers only show image files in file browse dialog.
<o:inputFile value="#{bean.file}" accept="image/*" />
And, file size validation via a custom maxsize
attribute has been added which runs in both client and server side. The below example sets the file size limit to 10MiB.
<o:inputFile value="#{bean.file}" maxsize="#{10 * 1024 * 1024}" />
In client side JavaScript, the new HTML5 File API will be used to check the file size and a special ajax request will be sent to trigger a JSF faces message. This all will take place without that the whole file needs to be sent to the server side. Instant feedback thus. As fallback for older non-HTML5 clients and as safeguard against spoofed requests, the server side will validate the file size once again after the file is arrived over there.
Independent image service
The <o:graphicImage>
component, which was added in OmniFaces 2.0, had a builtin security restriction to prevent users from being able to invoke arbitrary bean methods by manipulating the GET request URL path. One of the consequences of this security restriction is that images served by <o:graphicImage>
component aren't consistently hotlinkable. It works only if the page referencing the <o:graphicImage>
has been invoked at least once in application's lifetime.
Therefore a new managed bean annotation has been introduced which should mark a bean as a dedicated and public graphic image service. When putting @GraphicImageBean
annotation on the bean, then all of bean's public methods which return either InputStream
or byte[]
will become accessible by a direct GET request URL.
import org.omnifaces.cdi.GraphicImageBean;
@GraphicImageBean
public class Images {
@Inject
private ImageService service;
public byte[] get(Long id) {
return service.getContent(id);
}
}
This also allowed the creation of a bunch of new EL functions such as #{of:graphicImageURL(...)}
which merely print the graphic image URL without the need for a whole <o:graphicImage>
component, which finally makes the below case possible:
<a href="#{of:graphicImageURL('images.full(product.imageId)')}">
<o:graphicImage value="#{images.thumb(product.imageId)}" />
</a>
import org.omnifaces.cdi.GraphicImageBean;
@GraphicImageBean
public class Images {
@Inject
private ImageService service;
public byte[] full(Long id) {
return service.getFullContent(id);
}
public byte[] thumb(Long id) {
return service.getThumbContent(id);
}
}
MultiViews
Ones who are familiar with Apache HTTPD+PHP world are probably aware of the age-old but very useful MultiViews feature of Apache HTTPD which allowed usage of clean URLs such as http://example.com/foo/bar/baz
which searches for respectively /foo/bar/baz.php
, /foo/bar.php
and /foo.php
until the first one is found, and then passes the rest of the URL as PATH_INFO
variable.
The OmniFaces-builtin extensionless URL feature known as FacesViews has been enhanced to support exactly this MultiViews feature too. It's a matter of adding /*
suffix to the org.omnifaces.FACES_VIEWS_SCAN_PATHS
context parameter value. The below context parameter makes all files in the current webapp available via extensionless URLs with MultiViews support.
<context-param>
<param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
<param-value>/*.xhtml/*</param-value>
</context-param>
With above configuration, an URL such as http://example.com/contextpath/foo/bar/baz
will search for /foo/bar/baz.xhtml
, /foo/bar.xhtml
and /foo.xhtml
in this order until the first one is found and then invoke it. The existing @Param
annotation has been enhanced to inject path parameters by their index. Assuming that you've a /foo.xhtml
, then the path parameters bar
and baz
can be injected in the managed bean associated with /foo.xhtml
as below:
@Inject @Param(pathIndex=0)
private String bar;
@Inject @Param(pathIndex=1)
private String baz;
Maven download stats
Here are the Maven download stats after previous release:
- July 2016: 8560
- August 2016: 8660
- September 2016: 9341