See: Description
Class | Description |
---|---|
FacesViews |
FacesViews 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.
|
FacesViewsForwardingFilter |
This filter makes sure extensionless requests arrive at the FacesServlet using an extension on which that Servlet is mapped,
and that non-extensionless requests are handled according to a set preference.
|
FacesViewsInitializer |
Convenience class for Servlet 3.0 users, which will auto-register most artifacts
required for auto-mapping and extensionless view to work.
|
FacesViewsInitializerListener |
Convenience class for Servlet 3.0 users, which will map the FacesServlet to extensions found
during scanning in
FacesViewsInitializer . |
FacesViewsJSF2ExternalContextFactory |
External context factory that installs an external context which locates resources just
like the
FacesViewsResolver does. |
FacesViewsJSF2ExternalContextFactory.FacesViewsJSF2ExternalContext | |
FacesViewsResolver |
Facelets resource resolver that resolves mapped resources (views) to the folders from which
those views were scanned (like the the special auto-scanned faces-views folder).
|
FacesViewsViewHandler |
View handler that renders an action URL extensionless if a resource is a mapped one, and faces views has been set to always
render extensionless or if the current request is extensionless, otherwise as-is.
|
UriExtensionRequestWrapper |
This wraps a request to an extensionless JSF view and provides an extension for
all methods that reveal the servlet path.
|
Enum | Description |
---|---|
ExtensionAction |
The action that is done when a Faces Views request with an extension is done.
|
FacesServletDispatchMethod |
The method used by FacesViews to invoke the FacesServlet.
|
PathAction |
The action that is done when a request for a public path from which faces views where scanned is done.
|
ViewHandlerMode |
The mode of the view handler with respect to constructing an action URL.
|
This package contains the classes for the OmniFaces' FacesViews feature.
FacesViews is a feature where a special dedicated directory (/WEB-INF/faces-views
), or optionally
one or more user specified directories, can be used to store Facelets source files.
All files found in these directory are automatically mapped as Facelets files and made available using both their original extension as well as without an extension (extensionless). Optionally scanning can be restricted to include only certain extensions.
With FacesViews, there is thus no need to list all Facelets views that should be accessed without an extension in some configuration file. Additionally, it thus automatically maps Facelets files to their original file extension, which prevents exposing the source code of those Facelets that happens with the default JSF mapping.
In Servlet 3.0 containers, scanning is done automatically and no further configuration is needed. The feature
is compatible with applications that don't have web.xml
or faces-config.xml
configuration
files. As such, it can be used as an alternative to declaring the FacesServlet
in web.xml
for the .xhtml
to .xhtml
mapping.
Example 1:
Consider the following file structure and assume no further configuration has been done:
/WEB-INF/faces-views/index.xhtml /WEB-INF/faces-views/users/add.xhtml /normal.xhtml
This will make the Facelets available via the following URLs (given a root deployment on domain example.com
):
example.com/index example.com/users/add example.com/index.xhtml (will direct to /index by default) example.com/users/add.xhtml (will direct to /users/add by default) example.com/normal.xhtml
Note that although the directory outside /WEB-INF/faces-views
is not scanned, the FacesServlet
is mapped on all extensions found in /WEB-INF/faces-views
, so this will also affect files outside
this directory. In the above example normal.xhtml
is thus also available via the .xhtml
extension, since
the whole FacesServlet is mapped on this.
Also note that the extension variants of the scanned views will redirect to the extensionless variants. This behavior can be changed (see below), so that these views are either directly available (no redirect) or are not available at all.
Example 2:
Consider the following web.xml
:
<context-param> <param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name> <param-value>/*.xhtml</param-value> </context-param>
And this file structure:
/page1.xhtml /foo/page2.xhtml /WEB-INF/resources/template.xhtml /script.js
This will make the Facelets available via the following URLs (given a root deployment on domain example.com
):
example.com/page1 example.com/foo/page2 example.com/page1.xhtml (will direct to /page1 by default) example.com/foo/page2.xhtml (will direct to /foo/page2 by default)
Note that in the above example, /WEB-INF
was NOT scanned and thus template.xhtml
is not made publicly available. Likewise
/script.js
was also not scanned since it doesn't have the configured extension (.xhtml
). Finally, although a web.xml
was used, there
does not need to be a mapping for the FacesServlet
in it when using a Servlet 3.0 container.
If a <welcome-file>
is defined in web.xml
that's scanned by FacesViews AND REDIRECT_TO_EXTENSIONLESS
is used
(which is the default, see below), it's necessary to define an extensionless welcome file to prevent a request to /
being redirected to
/[welcome file]
. E.g. without this http://example.com
will redirect to say http://example.com/index
.
For example:
<welcome-file-list> <welcome-file>index</welcome-file> </welcome-file-list>
JSF normally inspects the request URI to derive a logical view id from it. It assumes the FacesServlet is either mapped on a prefix path or an extension, and will get confused when an extensionless "exactly mapped" request is encountered. To counter this, FacesViews makes use of a filter that intercepts each request and makes it appear to JSF that the request was a normal extension mapped one.
In order to do this dispatching, two methods are provided; forwarding, and wrapping the request and continuing the filter chain.
For the last method to work, the FacesServlet is programmatically mapped to every individual resource (page/view) that is encountered. By
default the filter is automatically registered and is inserted after all filters that are declared in web.xml
.
These internal details are important for users to be aware of, since they greatly influence how extensionless requests interact with other filter based functionality such as security filters, compression filters, file upload filters, etc.
With the forwarding method, filters typically have to be set to dispatch type FORWARD
as well. If the FacesView filter is the first
in the chain other filters that are set to dispatch type REQUEST
will NOT be invoked at all (the chain is ended). If the
FacesView filter is set to be the last, other filters will be invoked, but they should not modify the response (a forward clears
the response buffer till so far if not committed).
No such problems appear to exist when the FacesView filter simply continues the filtering chain. However, since it wraps the requess there might be unforeseen problems with containers or other filters that get confused when the request URI changes in the middle of the chain. Continuing the chain has been tested with JBoss EAP 6.0.1, GlassFish 3.1.2.2, WebLogic 12.1.1 and TomEE 1.5.2-snapshot and thus with both Mojarra and MyFaces. However, since it's a new method for OmniFaces 1.4 we kept the existing forward as an alternative.
The configuration options below provide more details about the dispatch methods and the filter position which can be used for tweaking FacesViews for interoperability with other filters.
The following context parameters are available.
"org.omnifaces.FACES_VIEWS_ENABLED" |
Used to completely switch scanning off.
Allowed values: { true ,false }
Default value: true
(note that if no /WEB-INF/faces-views directory is present and no explicit paths have been configured, no scanning will be done either) |
"org.omnifaces.FACES_VIEWS_SCAN_PATHS" |
A comma separated list of paths that are to be scanned in addition to /WEB-INF/faces-views .
Allowed values: any path relative to the web root, including the root path ( / ) and /WEB-INF .
A wildcard can be added to the path, which will cause only files with the given extension te be scanned.
Examples: - Scan all files in both folder1 and folder2: /folder1, /folder2
- Scan only .xhtml files in the root: /*.xhtml
Note that when the root path is given, all its sub paths are also scanned EXCEPT WEB-INF , META-INF and resources .
If those have to be scanned as well, they can be added to the list of paths explicitly.
Default value: /WEB-INF/faces-views (note when this value is set, those paths will be in addition to the default /WEB-INF/faces-views )
|
"org.omnifaces.FACES_VIEWS_SCANNED_VIEWS_ALWAYS_EXTENSIONLESS" |
Used to set how scanned views should be rendered in JSF controlled links.
With this setting set to false , it depends on whether the request URI uses an extension or not.
If it doesn't, links are also rendered without one, otherwise they are rendered with an extension.
When set to true links are always rendered without an extension.
Default value: true
|
"org.omnifaces.FACES_VIEWS_EXTENSION_ACTION" |
Determines the action that is performed whenever a resource is requested WITH extension that's also available without an extension.
Allowed values: { SEND_404 ,REDIRECT_TO_EXTENSIONLESS ,PROCEED }, which have the following meaning:
- SEND_404 : Send a 404 (not found), makes it look like e.g. /foo.xhtml never existed and there's only /foo .
- REDIRECT_TO_EXTENSIONLESS : Redirects to the same URL, but with the extension removed. E.g. /foo.xhtml is redirected to /foo .
- PROCEED : No special action is taken. Both /foo.xhtml and /foo are processed as-if they were separate views (with same content).
Default value: REDIRECT_TO_EXTENSIONLESS
|
"org.omnifaces.FACES_VIEWS_PATH_ACTION" |
Determines the action that is performed whenever a resource is requested in a public path that has been used for scanning views by faces views
(e.g. the paths set by "org.omnifaces.FACES_VIEWS_SCAN_PATHS" , but excluding the root path /).
Allowed values: { SEND_404 ,REDIRECT_TO_SCANNED_EXTENSIONLESS ,PROCEED }, which have the following meaning:
- SEND_404 : Send a 404 (not found), makes it look like e.g. /path/foo.xhtml never existed and there's only /foo and optionally /foo.xhtml .
- REDIRECT_TO_SCANNED_EXTENSIONLESS : Redirects to the resource corresponding with the one that was scanned. e.g. /path/foo.xml redirects to /foo .
- PROCEED : No special action is taken. /path/foo.xml and /foo (and optionally /foo.xhtml ) will be accessible.
Default value: REDIRECT_TO_EXTENSIONLESS
|
"org.omnifaces.FACES_VIEWS_DISPATCH_METHOD" |
Determines the method used by FacesViews to invoke the FacesServlet.
Allowed values: { FORWARD ,DO_FILTER }, which have the following meaning:
- FORWARD : Use a forward to invoke the FacesServlet . Using this method the FacesServlet does not have to be mapped to the (extensionless) requested resource or to everything (/*) when manually mapping.
- DO_FILTER : Use a plain FilterChain.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse) to invoke the FacesServlet . Using this method necessitates the FacesServlet to be mapped to the (extensionless) requested resource or to everything (/*) when manually mapping.
Default value: DO_FILTER
|
"org.omnifaces.FACES_VIEWS_VIEW_HANDLER_MODE" |
Determines how the FacesViewsViewHandler should build the action URL that's used in e.g. forms and links.
Allowed values: { STRIP_EXTENSION_FROM_PARENT , BUILD_WITH_PARENT_QUERY_PARAMETERS }, which have the following meaning:
- STRIP_EXTENSION_FROM_PARENT : Strip the extension from the parent view handler's outcome using the at runtime determined extension mapping of the FacesServlet. Requires Servlet 3.0+.
- BUILD_WITH_PARENT_QUERY_PARAMETERS : The FacesViewsViewHandler constructs the action URL itself and only takes the query parameters (if any) from the parent view handler outcome. This is mode is automatically selected on Servlet 2.5.
Default value: STRIP_EXTENSION_FROM_PARENT on Servlet 3.0+, BUILD_WITH_PARENT_QUERY_PARAMETERS on Servlet 2.5.
|
"org.omnifaces.FACES_VIEWS_FILTER_AFTER_DECLARED_FILTERS" |
Used to set whether the FacesViewsForwardingFilter should match before declared filters (false ) or after declared filters (true ),
when automatic scanning and mapping is used (as opposed to manually mapping the Servlet as explained in the Servlet 2.5 section below).
Default value: true (the FacesViews forwarding filter is the last in the filter chain)
|
Servlet 2.5 users will have to install the FacesViewsForwardingFilter
and
FacesViewsViewHandler
manually in web.xml
:
<filter> <filter-name>FacesViewsForwardingFilter</filter-name> <filter-class>org.omnifaces.facesviews.FacesViewsForwardingFilter</filter-class> </filter> <filter-mapping> <filter-name>FacesViewsForwardingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>org.omnifaces.FACES_VIEWS_DISPATCH_METHOD</param-name> <param-value>FORWARD</param-value> </context-param>
Note that the FORWARD
method has been set. Without that, the FacesServlet has to be mapped manually (also in web.xml) to
each and every view that is used. This is similar to how the welcome file (see below) has to be mapped to the FacesServlet for Servlet
2.5 users.
When an extensionless welcome file is defined in web.xml
(see above), the FacesServlet has to be explicitly mapped
to this welcome file for Servlet 2.5. E.g.
<welcome-file-list> <welcome-file>index</welcome-file> </welcome-file-list> <servlet> <servlet-name>facesServlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.xhtml</url-pattern> <url-pattern>/welcome</url-pattern> </servlet-mapping>
And this in faces-config.xml
<application> <view-handler>org.omnifaces.facesviews.FacesViewsViewHandler</view-handler> </application>
(at the moment Servlet 2.5 compatibility has not been tested thorougly)
In OmniFaces 1.4, a major overhaul was done for FacesViews and several things are done differently from how they were done in 1.3
Most notably is that the FacesServlet dispatch changed from forwarding to continuing the chain, the FacesView filter moved from being the first in the chain to being the last, links are always rendered as their extensionless variant independent of the request using an extension or not, and when a request with an extension is used anyway (e.g. by typing it directly into the address bar) it's now redirected to the extensionless variant.
By putting the following settings in web.xml
a behavior that most closely resembles 1.3 can be obtained:
<context-param> <param-name>org.omnifaces.FACES_VIEWS_DISPATCH_METHOD</param-name> <param-value>FORWARD</param-value> </context-param> <context-param> <param-name>org.omnifaces.FACES_VIEWS_FILTER_AFTER_DECLARED_FILTERS</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>org.omnifaces.FACES_VIEWS_SCANNED_VIEWS_ALWAYS_EXTENSIONLESS</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>org.omnifaces.FACES_VIEWS_EXTENSION_ACTION</param-name> <param-value>PROCEED</param-value> </context-param>
Copyright © 2012–2015 OmniFaces. All rights reserved.