I have a web-application where the users can be sent directly to some specific pages (such as a page where he can view or edit an item). To achieve that, we provide a specific url. These urls are located outside the current web-application (i.e. they can be present in another web-application, or in an email).
The url looks like http://myserver/my-app/forward.jsf?action=XXX¶m=YYY
, where:
- action represents the page where the user will be redirected. You can consider this as the
from-outcome
of any JSF action innavigation-case
infaces-config.xml
. - actionParam is a parameter for the previous action (generally an item ID)
So for example, I can have these kind of urls:
http://myserver/my-app/forward.jsf?action=viewItem&actionParam=1234
http://myserver/my-app/forward.jsf?action=editItem&actionParam=1234
Of course, I have a Java class (bean) that will check some security constraints (i.e. is the user allowed to see / edit the corresponding item?) and then redirect the user to the correct page (such as edit.xhtml
, view.xhtml
or access-denied.xhtml
).
Current implementation
Currently, we have a basic way to accomplish the forward. When the user clicks on the link, the following XHTML page is called:
<html>
<body id="forwardForm">
<h:inputHidden id="myAction" binding="#{forwardBean.hiddenAction}"/>
<h:inputHidden id="myParam" binding="#{forwardBean.hiddenActionParam}"/>
<h:commandButton id="forwardBtn" actionListener="#{forwardBean.doForward}" style="display: none;"/>
</body>
<script type="text/javascript">
document.getElementById('forwardForm:forwardBtn').click();
</script>
</html>
As you can see, I bind two <h:inputHidden>
components in my Java bean. They will be used to store the value of both action
and actionParam
request parameter (using FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("actiontParam");
). I also provide the doForward
method that which will be called immediately when the page is rendered, which will redirect (again) the user to the real page. The method is:
public void doForward(ActionEvent evt) {
FacesContext facesContext = FacesContext.getCurrentInstance();
String redirect = // define the navigation rule that must be used in order to redirect the user to the adequate page...
NavigationHandler myNav = facesContext.getApplication().getNavigationHandler();
myNav.handleNavigation(facesContext, null, redirect);
}
This solution is working, but I have two problems with that:
- I don't like the way it is implemented. I'm sure that I can have something simplier (using a Servlet?).
- This solution is using Javascript, and I must not use Javascript (as this forward may be used by old Blackberry users, where the Javascript is not supported).
So my question is how to refactor this redirection / forward feature?
Technical information
Java 1.6, JSF 1.2, Facelets, Richfaces