I am trying to implement a "generic" view where (part of) the content displayed depends on the URL. E.g.
If /somepath/somepage.xhtml
points to a non existing file, instead of going straight to a 404 error I want to try to retrieve /somepath/somepage.xhtml
's content from the database using a generic view, /genericview.xhtml
, where I have something like:
<h:outputText value="#{genericViewBean.content_lg}"
escape="false" />
which, if found by the backing bean, would output the content of the database entry from a tgenericcontent
table, depending on the originally requested viewId:
webpath | content
/somepath/somepage.xhtml | <p>This is a test</p>
/someotherpath/someotherpage.xhtml | <p>A different test</p>
If the view content is not found in that table then the standard 404 error would be returned.
The closest I got wast to clone /genericview.xhtml
changing only the file path (for example, to /somepath/somepage.xhtml
). But that gets me one exact copy of the file per view, it is quite messy, and it doesn't allow me to create a new url just by adding an entry to my database.
How can I get the same result without cloning /genericview.xhtml
?
(P.S: I have read about prettyfaces, but isn't there a simpler solution?)
For that, normally a servlet filter is being used. PrettyFaces, UrlRewriteFilter and FacesViews also do it that way.
You can get the request URI by
HttpServletRequest#getRequestURI()
. You can check the existence of a web resource byServletContext#getResource()
which will returnnull
on non-existent resources. If the resource exists, just continue the request byFilterChain#doFilter()
, else forward the request to the generic view byRequestDispatcher#forward()
.All in all, this is how the filter could look like:
In the
/genericview.xhtml
, the original request URI is available as request attribute keyed withRequestDispatcher#FORWARD_REQUEST_URI
. You could use it in@PostConstruct
of backing bean associated with the view in order to pull the right content from the DB.